diff options
Diffstat (limited to 'contrib/llvm-project/lldb/source/Host/common/Editline.cpp')
-rw-r--r-- | contrib/llvm-project/lldb/source/Host/common/Editline.cpp | 172 |
1 files changed, 98 insertions, 74 deletions
diff --git a/contrib/llvm-project/lldb/source/Host/common/Editline.cpp b/contrib/llvm-project/lldb/source/Host/common/Editline.cpp index d3a70aeaa326..3e655244b107 100644 --- a/contrib/llvm-project/lldb/source/Host/common/Editline.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/Editline.cpp @@ -14,6 +14,7 @@ #include "lldb/Host/Editline.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" +#include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/SelectHelper.h" @@ -863,26 +864,59 @@ unsigned char Editline::BufferEndCommand(int ch) { /// Prints completions and their descriptions to the given file. Only the /// completions in the interval [start, end) are printed. -static void PrintCompletion(FILE *output_file, size_t start, size_t end, - StringList &completions, StringList &descriptions) { - // This is an 'int' because of printf. - int max_len = 0; - - for (size_t i = start; i < end; i++) { - const char *completion_str = completions.GetStringAtIndex(i); - max_len = std::max((int)strlen(completion_str), max_len); +static void +PrintCompletion(FILE *output_file, + llvm::ArrayRef<CompletionResult::Completion> results, + size_t max_len) { + for (const CompletionResult::Completion &c : results) { + fprintf(output_file, "\t%-*s", (int)max_len, c.GetCompletion().c_str()); + if (!c.GetDescription().empty()) + fprintf(output_file, " -- %s", c.GetDescription().c_str()); + fprintf(output_file, "\n"); } +} + +static void +DisplayCompletions(::EditLine *editline, FILE *output_file, + llvm::ArrayRef<CompletionResult::Completion> results) { + assert(!results.empty()); - for (size_t i = start; i < end; i++) { - const char *completion_str = completions.GetStringAtIndex(i); - const char *description_str = descriptions.GetStringAtIndex(i); + fprintf(output_file, "\n" ANSI_CLEAR_BELOW "Available completions:\n"); + const size_t page_size = 40; + bool all = false; - if (completion_str) - fprintf(output_file, "\n\t%-*s", max_len, completion_str); + auto longest = + std::max_element(results.begin(), results.end(), [](auto &c1, auto &c2) { + return c1.GetCompletion().size() < c2.GetCompletion().size(); + }); - // Print the description if we got one. - if (description_str && strlen(description_str)) - fprintf(output_file, " -- %s", description_str); + const size_t max_len = longest->GetCompletion().size(); + + if (results.size() < page_size) { + PrintCompletion(output_file, results, max_len); + return; + } + + size_t cur_pos = 0; + while (cur_pos < results.size()) { + size_t remaining = results.size() - cur_pos; + size_t next_size = all ? remaining : std::min(page_size, remaining); + + PrintCompletion(output_file, results.slice(cur_pos, next_size), max_len); + + cur_pos += next_size; + + if (cur_pos >= results.size()) + break; + + fprintf(output_file, "More (Y/n/a): "); + char reply = 'n'; + int got_char = el_getc(editline, &reply); + fprintf(output_file, "\n"); + if (got_char == -1 || reply == 'n') + break; + if (reply == 'a') + all = true; } } @@ -891,74 +925,64 @@ unsigned char Editline::TabCommand(int ch) { return CC_ERROR; const LineInfo *line_info = el_line(m_editline); - StringList completions, descriptions; - int page_size = 40; - const int num_completions = m_completion_callback( - line_info->buffer, line_info->cursor, line_info->lastchar, - 0, // Don't skip any matches (start at match zero) - -1, // Get all the matches - completions, descriptions, m_completion_callback_baton); + llvm::StringRef line(line_info->buffer, + line_info->lastchar - line_info->buffer); + unsigned cursor_index = line_info->cursor - line_info->buffer; + CompletionResult result; + CompletionRequest request(line, cursor_index, result); - if (num_completions == 0) + m_completion_callback(request, m_completion_callback_baton); + + llvm::ArrayRef<CompletionResult::Completion> results = result.GetResults(); + + StringList completions; + result.GetMatches(completions); + + if (results.size() == 0) return CC_ERROR; - // if (num_completions == -1) - // { - // el_insertstr (m_editline, m_completion_key); - // return CC_REDISPLAY; - // } - // else - if (num_completions == -2) { - // Replace the entire line with the first string... - el_deletestr(m_editline, line_info->cursor - line_info->buffer); - el_insertstr(m_editline, completions.GetStringAtIndex(0)); + + if (results.size() == 1) { + CompletionResult::Completion completion = results.front(); + switch (completion.GetMode()) { + case CompletionMode::Normal: { + std::string to_add = completion.GetCompletion(); + to_add = to_add.substr(request.GetCursorArgumentPrefix().size()); + if (request.GetParsedArg().IsQuoted()) + to_add.push_back(request.GetParsedArg().GetQuoteChar()); + to_add.push_back(' '); + el_insertstr(m_editline, to_add.c_str()); + break; + } + case CompletionMode::Partial: { + std::string to_add = completion.GetCompletion(); + to_add = to_add.substr(request.GetCursorArgumentPrefix().size()); + el_insertstr(m_editline, to_add.c_str()); + break; + } + case CompletionMode::RewriteLine: { + el_deletestr(m_editline, line_info->cursor - line_info->buffer); + el_insertstr(m_editline, completion.GetCompletion().c_str()); + break; + } + } return CC_REDISPLAY; } // If we get a longer match display that first. - const char *completion_str = completions.GetStringAtIndex(0); - if (completion_str != nullptr && *completion_str != '\0') { - el_insertstr(m_editline, completion_str); + std::string longest_prefix = completions.LongestCommonPrefix(); + if (!longest_prefix.empty()) + longest_prefix = + longest_prefix.substr(request.GetCursorArgumentPrefix().size()); + if (!longest_prefix.empty()) { + el_insertstr(m_editline, longest_prefix.c_str()); return CC_REDISPLAY; } - if (num_completions > 1) { - int num_elements = num_completions + 1; - fprintf(m_output_file, "\n" ANSI_CLEAR_BELOW "Available completions:"); - if (num_completions < page_size) { - PrintCompletion(m_output_file, 1, num_elements, completions, - descriptions); - fprintf(m_output_file, "\n"); - } else { - int cur_pos = 1; - char reply; - int got_char; - while (cur_pos < num_elements) { - int endpoint = cur_pos + page_size; - if (endpoint > num_elements) - endpoint = num_elements; - - PrintCompletion(m_output_file, cur_pos, endpoint, completions, - descriptions); - cur_pos = endpoint; - - if (cur_pos >= num_elements) { - fprintf(m_output_file, "\n"); - break; - } - - fprintf(m_output_file, "\nMore (Y/n/a): "); - reply = 'n'; - got_char = el_getc(m_editline, &reply); - if (got_char == -1 || reply == 'n') - break; - if (reply == 'a') - page_size = num_elements - cur_pos; - } - } - DisplayInput(); - MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingCursor); - } + DisplayCompletions(m_editline, m_output_file, results); + + DisplayInput(); + MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingCursor); return CC_REDISPLAY; } |