1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-23 20:57:41 +00:00

LibLine: Make the comments follow the project style

This commit is contained in:
AnotherTest 2020-05-23 03:19:48 +04:30 committed by Andreas Kling
parent 3c3edf5831
commit 909ac2a558
6 changed files with 81 additions and 83 deletions

View file

@ -294,7 +294,7 @@ String Editor::get_line(const String& prompt)
auto reverse_tab = false; auto reverse_tab = false;
auto ctrl_held = false; auto ctrl_held = false;
// discard starting bytes until they make sense as utf-8 // Discard starting bytes until they make sense as utf-8.
size_t valid_bytes = 0; size_t valid_bytes = 0;
while (nread) { while (nread) {
Utf8View { StringView { m_incomplete_data.data(), (size_t)nread } }.validate(valid_bytes); Utf8View { StringView { m_incomplete_data.data(), (size_t)nread } }.validate(valid_bytes);
@ -395,8 +395,8 @@ String Editor::get_line(const String& prompt)
case 'C': // right case 'C': // right
if (m_cursor < m_buffer.size()) { if (m_cursor < m_buffer.size()) {
if (ctrl_held) { if (ctrl_held) {
// temporarily put a space at the end of our buffer // Temporarily put a space at the end of our buffer,
// this greatly simplifies the logic below // doing this greatly simplifies the logic below.
m_buffer.append(' '); m_buffer.append(' ');
for (;;) { for (;;) {
if (m_cursor >= m_buffer.size()) if (m_cursor >= m_buffer.size())
@ -476,25 +476,25 @@ String Editor::get_line(const String& prompt)
if (!on_tab_complete) if (!on_tab_complete)
continue; continue;
// reverse tab can count as regular tab here // Reverse tab can count as regular tab here.
m_times_tab_pressed++; m_times_tab_pressed++;
int token_start = m_cursor; int token_start = m_cursor;
// ask for completions only on the first tab // Ask for completions only on the first tab
// and scan for the largest common prefix to display // and scan for the largest common prefix to display,
// further tabs simply show the cached completions // further tabs simply show the cached completions.
if (m_times_tab_pressed == 1) { if (m_times_tab_pressed == 1) {
m_suggestion_manager.set_suggestions(on_tab_complete(*this)); m_suggestion_manager.set_suggestions(on_tab_complete(*this));
m_prompt_lines_at_suggestion_initiation = num_lines(); m_prompt_lines_at_suggestion_initiation = num_lines();
if (m_suggestion_manager.count() == 0) { if (m_suggestion_manager.count() == 0) {
// there are no suggestions, beep~ // There are no suggestions, beep.
putchar('\a'); putchar('\a');
fflush(stdout); fflush(stdout);
} }
} }
// Adjust already incremented / decremented index when switching tab direction // Adjust already incremented / decremented index when switching tab direction.
if (reverse_tab && m_tab_direction != TabDirection::Backward) { if (reverse_tab && m_tab_direction != TabDirection::Backward) {
m_suggestion_manager.previous(); m_suggestion_manager.previous();
m_suggestion_manager.previous(); m_suggestion_manager.previous();
@ -523,7 +523,7 @@ String Editor::get_line(const String& prompt)
insert(view); insert(view);
if (completion_result.style_to_apply.has_value()) { if (completion_result.style_to_apply.has_value()) {
// Apply the style of the last suggestion // Apply the style of the last suggestion.
readjust_anchored_styles(m_suggestion_manager.current_suggestion().start_index, ModificationKind::ForcedOverlapRemoval); readjust_anchored_styles(m_suggestion_manager.current_suggestion().start_index, ModificationKind::ForcedOverlapRemoval);
stylize({ m_suggestion_manager.current_suggestion().start_index, m_cursor, Span::Mode::CodepointOriented }, completion_result.style_to_apply.value()); stylize({ m_suggestion_manager.current_suggestion().start_index, m_cursor, Span::Mode::CodepointOriented }, completion_result.style_to_apply.value());
} }
@ -560,9 +560,9 @@ String Editor::get_line(const String& prompt)
} }
if (m_suggestion_manager.count() < 2) { if (m_suggestion_manager.count() < 2) {
// we have none, or just one suggestion // We have none, or just one suggestion,
// we should just commit that and continue // we should just commit that and continue
// after it, as if it were auto-completed // after it, as if it were auto-completed.
suggest(0, 0, Span::CodepointOriented); suggest(0, 0, Span::CodepointOriented);
m_times_tab_pressed = 0; m_times_tab_pressed = 0;
m_suggestion_manager.reset(); m_suggestion_manager.reset();
@ -572,11 +572,11 @@ String Editor::get_line(const String& prompt)
} }
if (m_times_tab_pressed) { if (m_times_tab_pressed) {
// Apply the style of the last suggestion // Apply the style of the last suggestion.
readjust_anchored_styles(m_suggestion_manager.current_suggestion().start_index, ModificationKind::ForcedOverlapRemoval); readjust_anchored_styles(m_suggestion_manager.current_suggestion().start_index, ModificationKind::ForcedOverlapRemoval);
stylize({ m_suggestion_manager.current_suggestion().start_index, m_cursor, Span::Mode::CodepointOriented }, m_suggestion_manager.current_suggestion().style); stylize({ m_suggestion_manager.current_suggestion().start_index, m_cursor, Span::Mode::CodepointOriented }, m_suggestion_manager.current_suggestion().style);
// we probably have some suggestions drawn // We probably have some suggestions drawn,
// let's clean them up // let's clean them up.
if (m_suggestion_display->cleanup()) { if (m_suggestion_display->cleanup()) {
reposition_cursor(); reposition_cursor();
m_refresh_needed = true; m_refresh_needed = true;
@ -599,7 +599,7 @@ String Editor::get_line(const String& prompt)
remove_at_index(m_cursor - 1); remove_at_index(m_cursor - 1);
--m_cursor; --m_cursor;
m_inline_search_cursor = m_cursor; m_inline_search_cursor = m_cursor;
// we will have to redraw :( // We will have to redraw :(
m_refresh_needed = true; m_refresh_needed = true;
}; };
@ -661,15 +661,15 @@ String Editor::get_line(const String& prompt)
return; return;
}; };
// whenever the search editor gets a ^R, cycle between history entries // Whenever the search editor gets a ^R, cycle between history entries.
m_search_editor->register_character_input_callback(0x12, [this](Editor& search_editor) { m_search_editor->register_character_input_callback(0x12, [this](Editor& search_editor) {
++m_search_offset; ++m_search_offset;
search_editor.m_refresh_needed = true; search_editor.m_refresh_needed = true;
return false; // Do not process this key event return false; // Do not process this key event
}); });
// whenever the search editor gets a backspace, cycle back between history entries // Whenever the search editor gets a backspace, cycle back between history entries
// unless we're at the zeroth entry, in which case, allow the deletion // unless we're at the zeroth entry, in which case, allow the deletion.
m_search_editor->register_character_input_callback(m_termios.c_cc[VERASE], [this](Editor& search_editor) { m_search_editor->register_character_input_callback(m_termios.c_cc[VERASE], [this](Editor& search_editor) {
if (m_search_offset > 0) { if (m_search_offset > 0) {
--m_search_offset; --m_search_offset;
@ -682,7 +682,7 @@ String Editor::get_line(const String& prompt)
// ^L - This is a source of issues, as the search editor refreshes first, // ^L - This is a source of issues, as the search editor refreshes first,
// and we end up with the wrong order of prompts, so we will first refresh // and we end up with the wrong order of prompts, so we will first refresh
// ourselves, then refresh the search editor, and then tell him not to process // ourselves, then refresh the search editor, and then tell him not to process
// this event // this event.
m_search_editor->register_character_input_callback(0x0c, [this](auto& search_editor) { m_search_editor->register_character_input_callback(0x0c, [this](auto& search_editor) {
printf("\033[3J\033[H\033[2J"); // Clear screen. printf("\033[3J\033[H\033[2J"); // Clear screen.
@ -716,7 +716,7 @@ String Editor::get_line(const String& prompt)
m_is_searching = false; m_is_searching = false;
m_search_offset = 0; m_search_offset = 0;
// manually cleanup the search line // Manually cleanup the search line.
reposition_cursor(); reposition_cursor();
auto search_string_codepoint_length = Utf8View { search_string }.length_in_codepoints(); auto search_string_codepoint_length = Utf8View { search_string }.length_in_codepoints();
VT::clear_lines(0, (search_string_codepoint_length + actual_rendered_string_length(search_prompt) + m_num_columns - 1) / m_num_columns); VT::clear_lines(0, (search_string_codepoint_length + actual_rendered_string_length(search_prompt) + m_num_columns - 1) / m_num_columns);
@ -724,14 +724,13 @@ String Editor::get_line(const String& prompt)
reposition_cursor(); reposition_cursor();
if (!m_reset_buffer_on_search_end || search_string_codepoint_length == 0) { if (!m_reset_buffer_on_search_end || search_string_codepoint_length == 0) {
// if the entry was empty, or we purposely quit without a newline, // If the entry was empty, or we purposely quit without a newline,
// do not return anything // do not return anything; instead, just end the search.
// instead, just end the search
end_search(); end_search();
continue; continue;
} }
// return the string // Return the string,
finish(); finish();
continue; continue;
} }
@ -741,7 +740,7 @@ String Editor::get_line(const String& prompt)
if (codepoint == m_termios.c_cc[VEOF]) { if (codepoint == m_termios.c_cc[VEOF]) {
if (m_buffer.is_empty()) { if (m_buffer.is_empty()) {
printf("<EOF>\n"); printf("<EOF>\n");
if (!m_always_refresh) // this is a little off, but it'll do for now if (!m_always_refresh) // This is a little off, but it'll do for now
exit(0); exit(0);
} }
continue; continue;
@ -774,7 +773,7 @@ bool Editor::search(const StringView& phrase, bool allow_empty, bool from_beginn
int last_matching_offset = -1; int last_matching_offset = -1;
// do not search for empty strings // Do not search for empty strings.
if (allow_empty || phrase.length() > 0) { if (allow_empty || phrase.length() > 0) {
size_t search_offset = m_search_offset; size_t search_offset = m_search_offset;
for (size_t i = m_history_cursor; i > 0; --i) { for (size_t i = m_history_cursor; i > 0; --i) {
@ -798,25 +797,25 @@ bool Editor::search(const StringView& phrase, bool allow_empty, bool from_beginn
if (last_matching_offset >= 0) { if (last_matching_offset >= 0) {
insert(m_history[last_matching_offset]); insert(m_history[last_matching_offset]);
} }
// always needed // Always needed, as we have cleared the buffer above.
m_refresh_needed = true; m_refresh_needed = true;
return last_matching_offset >= 0; return last_matching_offset >= 0;
} }
void Editor::recalculate_origin() void Editor::recalculate_origin()
{ {
// changing the columns can affect our origin if // Changing the columns can affect our origin if
// the new size is smaller than our prompt, which would // the new size is smaller than our prompt, which would
// cause said prompt to take up more space, so we should // cause said prompt to take up more space, so we should
// compensate for that // compensate for that.
if (m_cached_prompt_length >= m_num_columns) { if (m_cached_prompt_length >= m_num_columns) {
auto added_lines = (m_cached_prompt_length + 1) / m_num_columns - 1; auto added_lines = (m_cached_prompt_length + 1) / m_num_columns - 1;
m_origin_x += added_lines; m_origin_x += added_lines;
} }
// we also need to recalculate our cursor position // We also need to recalculate our cursor position,
// but that will be calculated and applied at the next // but that will be calculated and applied at the next
// refresh cycle // refresh cycle.
} }
void Editor::cleanup() void Editor::cleanup()
{ {
@ -830,8 +829,8 @@ void Editor::cleanup()
void Editor::refresh_display() void Editor::refresh_display()
{ {
auto has_cleaned_up = false; auto has_cleaned_up = false;
// someone changed the window size, figure it out // Someone changed the window size, figure it out
// and react to it, we might need to redraw // and react to it, we might need to redraw.
if (m_was_resized) { if (m_was_resized) {
auto previous_num_columns = m_num_columns; auto previous_num_columns = m_num_columns;
@ -846,7 +845,7 @@ void Editor::refresh_display()
m_suggestion_display->set_vt_size(m_num_lines, m_num_columns); m_suggestion_display->set_vt_size(m_num_lines, m_num_columns);
if (previous_num_columns != m_num_columns) { if (previous_num_columns != m_num_columns) {
// we need to cleanup and redo everything // We need to cleanup and redo everything.
m_cached_prompt_valid = false; m_cached_prompt_valid = false;
m_refresh_needed = true; m_refresh_needed = true;
swap(previous_num_columns, m_num_columns); swap(previous_num_columns, m_num_columns);
@ -856,9 +855,9 @@ void Editor::refresh_display()
has_cleaned_up = true; has_cleaned_up = true;
} }
} }
// do not call hook on pure cursor movement // Do not call hook on pure cursor movement.
if (m_cached_prompt_valid && !m_refresh_needed && m_pending_chars.size() == 0) { if (m_cached_prompt_valid && !m_refresh_needed && m_pending_chars.size() == 0) {
// probably just moving around // Probably just moving around.
reposition_cursor(); reposition_cursor();
m_cached_buffer_size = m_buffer.size(); m_cached_buffer_size = m_buffer.size();
return; return;
@ -869,8 +868,8 @@ void Editor::refresh_display()
if (m_cached_prompt_valid) { if (m_cached_prompt_valid) {
if (!m_refresh_needed && m_cursor == m_buffer.size()) { if (!m_refresh_needed && m_cursor == m_buffer.size()) {
// just write the characters out and continue // Just write the characters out and continue,
// no need to refresh the entire line // no need to refresh the entire line.
char null = 0; char null = 0;
m_pending_chars.append(&null, 1); m_pending_chars.append(&null, 1);
fputs((char*)m_pending_chars.data(), stdout); fputs((char*)m_pending_chars.data(), stdout);
@ -882,7 +881,7 @@ void Editor::refresh_display()
} }
} }
// ouch, reflow entire line // Ouch, reflow entire line.
// FIXME: handle multiline stuff // FIXME: handle multiline stuff
if (!has_cleaned_up) { if (!has_cleaned_up) {
cleanup(); cleanup();
@ -910,10 +909,10 @@ void Editor::refresh_display()
for (auto& applicable_style : anchored_ends) for (auto& applicable_style : anchored_ends)
style.unify_with(applicable_style.value); style.unify_with(applicable_style.value);
// Disable any style that should be turned off // Disable any style that should be turned off.
VT::apply_style(style, false); VT::apply_style(style, false);
// go back to defaults // Reapply styles for overlapping spans that include this one.
style = find_applicable_style(i); style = find_applicable_style(i);
VT::apply_style(style, true); VT::apply_style(style, true);
} }
@ -926,7 +925,7 @@ void Editor::refresh_display()
for (auto& applicable_style : anchored_starts) for (auto& applicable_style : anchored_starts)
style.unify_with(applicable_style.value); style.unify_with(applicable_style.value);
// set new options // Set new styles.
VT::apply_style(style, true); VT::apply_style(style, true);
} }
builder.clear(); builder.clear();
@ -998,7 +997,7 @@ void VT::move_relative(int x, int y)
Style Editor::find_applicable_style(size_t offset) const Style Editor::find_applicable_style(size_t offset) const
{ {
// walk through our styles and merge all that fit in the offset // Walk through our styles and merge all that fit in the offset.
Style style; Style style;
auto unify = [&](auto& entry) { auto unify = [&](auto& entry) {
if (entry.key >= offset) if (entry.key >= offset)
@ -1055,14 +1054,14 @@ String Style::Hyperlink::to_vt_escape(bool starting) const
void Style::unify_with(const Style& other, bool prefer_other) void Style::unify_with(const Style& other, bool prefer_other)
{ {
// unify colors // Unify colors.
if (prefer_other || m_background.is_default()) if (prefer_other || m_background.is_default())
m_background = other.background(); m_background = other.background();
if (prefer_other || m_foreground.is_default()) if (prefer_other || m_foreground.is_default())
m_foreground = other.foreground(); m_foreground = other.foreground();
// unify graphic renditions // Unify graphic renditions.
if (other.bold()) if (other.bold())
set(Bold); set(Bold);
@ -1072,7 +1071,7 @@ void Style::unify_with(const Style& other, bool prefer_other)
if (other.underline()) if (other.underline())
set(Underline); set(Underline);
// unify links // Unify links.
if (prefer_other || m_hyperlink.is_empty()) if (prefer_other || m_hyperlink.is_empty())
m_hyperlink = other.hyperlink(); m_hyperlink = other.hyperlink();
} }
@ -1137,10 +1136,10 @@ void VT::apply_style(const Style& style, bool is_starting)
void VT::clear_lines(size_t count_above, size_t count_below) void VT::clear_lines(size_t count_above, size_t count_below)
{ {
// go down count_below lines // Go down count_below lines.
if (count_below > 0) if (count_below > 0)
printf("\033[%dB", (int)count_below); printf("\033[%dB", (int)count_below);
// then clear lines going upwards // Then clear lines going upwards.
for (size_t i = count_below + count_above; i > 0; --i) for (size_t i = count_below + count_above; i > 0; --i)
fputs(i == 1 ? "\033[2K" : "\033[2K\033[A", stdout); fputs(i == 1 ? "\033[2K" : "\033[2K\033[A", stdout);
} }
@ -1180,13 +1179,12 @@ size_t Editor::actual_rendered_string_length(const StringView& string) const
auto c = *it; auto c = *it;
switch (state) { switch (state) {
case Free: case Free:
if (c == '\x1b') { if (c == '\x1b') { // escape
// escape
state = Escape; state = Escape;
continue; continue;
} }
if (c == '\r' || c == '\n') { if (c == '\r' || c == '\n') { // return or carriage return
// reset length to 0, since we either overwrite, or are on a newline // Reset length to 0, since we either overwrite, or are on a newline.
length = 0; length = 0;
continue; continue;
} }
@ -1235,8 +1233,8 @@ Vector<size_t, 2> Editor::vt_dsr()
char buf[16]; char buf[16];
u32 length { 0 }; u32 length { 0 };
// read whatever junk there is before talking to the terminal // Read whatever junk there is before talking to the terminal
// and insert them later when we're reading user input // and insert them later when we're reading user input.
bool more_junk_to_read { false }; bool more_junk_to_read { false };
timeval timeout { 0, 0 }; timeval timeout { 0, 0 };
fd_set readfds; fd_set readfds;
@ -1311,7 +1309,7 @@ bool Editor::should_break_token(Vector<u32, 1024>& buffer, size_t index)
void Editor::remove_at_index(size_t index) void Editor::remove_at_index(size_t index)
{ {
// see if we have any anchored styles, and reposition them if needed // See if we have any anchored styles, and reposition them if needed.
readjust_anchored_styles(index, ModificationKind::Removal); readjust_anchored_styles(index, ModificationKind::Removal);
m_buffer.remove(index); m_buffer.remove(index);
} }
@ -1331,21 +1329,21 @@ void Editor::readjust_anchored_styles(size_t hint_index, ModificationKind modifi
for (auto& end_entry : start_entry.value) { for (auto& end_entry : start_entry.value) {
if (forced_removal) { if (forced_removal) {
if (start_entry.key <= hint_index && end_entry.key > hint_index) { if (start_entry.key <= hint_index && end_entry.key > hint_index) {
// remove any overlapping regions // Remove any overlapping regions.
continue; continue;
} }
} }
if (start_entry.key >= hint_index) { if (start_entry.key >= hint_index) {
if (start_entry.key == hint_index && end_entry.key == hint_index + 1 && modification == ModificationKind::Removal) { if (start_entry.key == hint_index && end_entry.key == hint_index + 1 && modification == ModificationKind::Removal) {
// remove the anchor, as all its text was wiped // Remove the anchor, as all its text was wiped.
continue; continue;
} }
// shift everything // Shift everything.
anchors_to_relocate.append({ { start_entry.key, end_entry.key, Span::Mode::CodepointOriented }, { start_entry.key + index_shift, end_entry.key + index_shift, Span::Mode::CodepointOriented }, end_entry.value }); anchors_to_relocate.append({ { start_entry.key, end_entry.key, Span::Mode::CodepointOriented }, { start_entry.key + index_shift, end_entry.key + index_shift, Span::Mode::CodepointOriented }, end_entry.value });
continue; continue;
} }
if (end_entry.key > hint_index) { if (end_entry.key > hint_index) {
// shift just the end // Shift just the end.
anchors_to_relocate.append({ { start_entry.key, end_entry.key, Span::Mode::CodepointOriented }, { start_entry.key, end_entry.key + index_shift, Span::Mode::CodepointOriented }, end_entry.value }); anchors_to_relocate.append({ { start_entry.key, end_entry.key, Span::Mode::CodepointOriented }, { start_entry.key, end_entry.key + index_shift, Span::Mode::CodepointOriented }, end_entry.value });
continue; continue;
} }
@ -1355,7 +1353,7 @@ void Editor::readjust_anchored_styles(size_t hint_index, ModificationKind modifi
m_anchored_spans_ending.clear(); m_anchored_spans_ending.clear();
m_anchored_spans_starting.clear(); m_anchored_spans_starting.clear();
// pass over the relocations and update the stale entries // Pass over the relocations and update the stale entries.
for (auto& relocation : anchors_to_relocate) { for (auto& relocation : anchors_to_relocate) {
stylize(relocation.new_span, relocation.style); stylize(relocation.new_span, relocation.style);
} }

View file

@ -109,8 +109,8 @@ public:
Function<void()> on_interrupt_handled; Function<void()> on_interrupt_handled;
Function<void(Editor&)> on_display_refresh; Function<void(Editor&)> on_display_refresh;
// FIXME: we will have to kindly ask our instantiators to set our signal handlers // FIXME: we will have to kindly ask our instantiators to set our signal handlers,
// since we can not do this cleanly ourselves (signal() limitation: cannot give member functions) // since we can not do this cleanly ourselves. (signal() limitation: cannot give member functions)
void interrupted() void interrupted()
{ {
if (m_is_editing) if (m_is_editing)
@ -124,7 +124,7 @@ public:
String line() const { return line(m_buffer.size()); } String line() const { return line(m_buffer.size()); }
String line(size_t up_to_index) const; String line(size_t up_to_index) const;
// only makes sense inside a char_input callback or on_* callback // Only makes sense inside a character_input callback or on_* callback.
void set_prompt(const String& prompt) void set_prompt(const String& prompt)
{ {
if (m_cached_prompt_valid) if (m_cached_prompt_valid)
@ -291,7 +291,7 @@ private:
size_t m_prompt_lines_at_suggestion_initiation { 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.
size_t m_origin_x { 0 }; size_t m_origin_x { 0 };
size_t m_origin_y { 0 }; size_t m_origin_y { 0 };
@ -311,7 +311,7 @@ private:
HashMap<char, NonnullOwnPtr<KeyCallback>> m_key_callbacks; HashMap<char, NonnullOwnPtr<KeyCallback>> m_key_callbacks;
// TODO: handle signals internally // TODO: handle signals internally.
struct termios m_termios, m_default_termios; struct termios m_termios, m_default_termios;
bool m_was_interrupted { false }; bool m_was_interrupted { false };
bool m_was_resized { false }; bool m_was_resized { false };

View file

@ -124,7 +124,7 @@ public:
static constexpr ItalicTag Italic {}; static constexpr ItalicTag Italic {};
static constexpr AnchoredTag Anchored {}; static constexpr AnchoredTag Anchored {};
// prepare for the horror of templates // Prepare for the horror of templates.
template<typename T, typename... Rest> template<typename T, typename... Rest>
Style(const T& style_arg, Rest... rest) Style(const T& style_arg, Rest... rest)
: Style(rest...) : Style(rest...)

View file

@ -148,15 +148,15 @@ SuggestionManager::CompletionAttemptResult SuggestionManager::attempt_completion
set_current_suggestion_initiation_index(initiation_start_index); set_current_suggestion_initiation_index(initiation_start_index);
if (mode == CompletePrefix) { if (mode == CompletePrefix) {
// only auto-complete *if possible* // Only auto-complete *if possible*.
if (can_complete) { if (can_complete) {
result.insert.append(suggestion.text_view.substring_view(m_next_suggestion_invariant_offset, m_largest_common_suggestion_prefix_length - m_next_suggestion_invariant_offset)); result.insert.append(suggestion.text_view.substring_view(m_next_suggestion_invariant_offset, m_largest_common_suggestion_prefix_length - m_next_suggestion_invariant_offset));
m_last_shown_suggestion_display_length = m_largest_common_suggestion_prefix_length; m_last_shown_suggestion_display_length = m_largest_common_suggestion_prefix_length;
// do not increment the suggestion index, as the first tab should only be a *peek* // Do not increment the suggestion index, as the first tab should only be a *peek*.
if (m_suggestions.size() == 1) { if (m_suggestions.size() == 1) {
// if there's one suggestion, commit and forget // If there's one suggestion, commit and forget.
result.new_completion_mode = DontComplete; result.new_completion_mode = DontComplete;
// add in the trivia of the last selected suggestion // Add in the trivia of the last selected suggestion.
result.insert.append(suggestion.trivia_view); result.insert.append(suggestion.trivia_view);
m_last_shown_suggestion_display_length = 0; m_last_shown_suggestion_display_length = 0;
result.style_to_apply = suggestion.style; result.style_to_apply = suggestion.style;
@ -171,7 +171,7 @@ SuggestionManager::CompletionAttemptResult SuggestionManager::attempt_completion
m_last_shown_suggestion = String::empty(); m_last_shown_suggestion = String::empty();
} else { } else {
result.insert.append(suggestion.text_view.substring_view(m_next_suggestion_invariant_offset, suggestion.text_view.length() - m_next_suggestion_invariant_offset)); result.insert.append(suggestion.text_view.substring_view(m_next_suggestion_invariant_offset, suggestion.text_view.length() - m_next_suggestion_invariant_offset));
// add in the trivia of the last selected suggestion // Add in the trivia of the last selected suggestion.
result.insert.append(suggestion.trivia_view); result.insert.append(suggestion.trivia_view);
m_last_shown_suggestion_display_length += suggestion.trivia_view.length(); m_last_shown_suggestion_display_length += suggestion.trivia_view.length();
} }

View file

@ -35,7 +35,7 @@
namespace Line { namespace Line {
// FIXME: These objects are pretty heavy since they store two copies of text // FIXME: These objects are pretty heavy since they store two copies of text
// somehow get rid of one // somehow get rid of one.
struct CompletionSuggestion { struct CompletionSuggestion {
private: private:
struct ForSearchTag { struct ForSearchTag {
@ -44,7 +44,7 @@ private:
public: public:
static constexpr ForSearchTag ForSearch {}; static constexpr ForSearchTag ForSearch {};
// intentionally not explicit (allows suggesting bare strings) // Intentionally not explicit. (To allow suggesting bare strings)
CompletionSuggestion(const String& completion) CompletionSuggestion(const String& completion)
: CompletionSuggestion(completion, "", {}) : CompletionSuggestion(completion, "", {})
{ {

View file

@ -55,8 +55,8 @@ void XtermSuggestionDisplay::display(const SuggestionManager& manager)
auto max_line_count = (m_prompt_length + longest_suggestion_length + m_num_columns - 1) / m_num_columns; auto max_line_count = (m_prompt_length + longest_suggestion_length + m_num_columns - 1) / m_num_columns;
if (longest_suggestion_length >= m_num_columns - 2) { if (longest_suggestion_length >= m_num_columns - 2) {
spans_entire_line = true; spans_entire_line = true;
// we should make enough space for the biggest entry in // We should make enough space for the biggest entry in
// the suggestion list to fit in the prompt line // the suggestion list to fit in the prompt line.
auto start = max_line_count - m_prompt_lines_at_suggestion_initiation; auto start = max_line_count - m_prompt_lines_at_suggestion_initiation;
for (size_t i = start; i < max_line_count; ++i) { for (size_t i = start; i < max_line_count; ++i) {
putchar('\n'); putchar('\n');
@ -70,7 +70,7 @@ void XtermSuggestionDisplay::display(const SuggestionManager& manager)
if (m_pages.is_empty()) { if (m_pages.is_empty()) {
size_t num_printed = 0; size_t num_printed = 0;
size_t lines_used = 1; size_t lines_used = 1;
// cache the pages // Cache the pages.
manager.set_start_index(0); manager.set_start_index(0);
size_t page_start = 0; size_t page_start = 0;
manager.for_each_suggestion([&](auto& suggestion, auto index) { manager.for_each_suggestion([&](auto& suggestion, auto index) {
@ -95,7 +95,7 @@ void XtermSuggestionDisplay::display(const SuggestionManager& manager)
return IterationDecision::Continue; return IterationDecision::Continue;
}); });
// last page // Append the last page.
m_pages.append({ page_start, manager.count() }); m_pages.append({ page_start, manager.count() });
} }
@ -113,12 +113,12 @@ void XtermSuggestionDisplay::display(const SuggestionManager& manager)
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 + m_prompt_lines_at_suggestion_initiation >= m_num_lines) if (lines_used + m_prompt_lines_at_suggestion_initiation >= m_num_lines)
return IterationDecision::Break; return IterationDecision::Break;
// only apply colour to the selection if something is *actually* added to the buffer // Only apply colour to the selection if something is *actually* added to the buffer.
if (manager.is_current_suggestion_complete() && index == manager.next_index()) { if (manager.is_current_suggestion_complete() && index == manager.next_index()) {
VT::apply_style({ Style::Foreground(Style::XtermColor::Blue) }); VT::apply_style({ Style::Foreground(Style::XtermColor::Blue) });
fflush(stdout); fflush(stdout);
@ -141,7 +141,7 @@ void XtermSuggestionDisplay::display(const SuggestionManager& manager)
m_lines_used_for_last_suggestions = lines_used; m_lines_used_for_last_suggestions = lines_used;
// if we filled the screen, move back the origin // If we filled the screen, move back the origin.
if (m_origin_x + lines_used >= m_num_lines) { if (m_origin_x + lines_used >= m_num_lines) {
m_origin_x = m_num_lines - lines_used; m_origin_x = m_num_lines - lines_used;
} }
@ -152,7 +152,7 @@ void XtermSuggestionDisplay::display(const SuggestionManager& manager)
auto string = String::format("%c page %d of %d %c", left_arrow, page_index + 1, m_pages.size(), right_arrow); auto string = String::format("%c page %d of %d %c", left_arrow, page_index + 1, m_pages.size(), right_arrow);
if (string.length() > m_num_columns - 1) { if (string.length() > m_num_columns - 1) {
// this would overflow into the next line, so just don't print an indicator // This would overflow into the next line, so just don't print an indicator.
return; return;
} }