Fix showing duplicate completion entries, always provide insertText.

This commit is contained in:
Jacob Dufault 2017-06-28 23:59:38 -07:00
parent b4000fa956
commit f498f0ccb1
4 changed files with 38 additions and 5 deletions

View File

@ -395,10 +395,6 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) {
ls_completion_item.documentation = clang::ToString(clang_getCompletionBriefComment(result.CompletionString)); ls_completion_item.documentation = clang::ToString(clang_getCompletionBriefComment(result.CompletionString));
ls_completion_item.sortText = (const char)uint64_t(GetCompletionPriority(result.CompletionString, result.CursorKind, ls_completion_item.label)); ls_completion_item.sortText = (const char)uint64_t(GetCompletionPriority(result.CompletionString, result.CursorKind, ls_completion_item.label));
// If this function is slow we can skip building insertText at the cost of some code duplication.
if (!IsCallKind(result.CursorKind))
ls_completion_item.insertText = "";
ls_result.push_back(ls_completion_item); ls_result.push_back(ls_completion_item);
} }
timer.ResetAndPrint("[complete] Building " + std::to_string(ls_result.size()) + " completion results"); timer.ResetAndPrint("[complete] Building " + std::to_string(ls_result.size()) + " completion results");

View File

@ -478,8 +478,17 @@ void FilterCompletionResponse(Out_TextDocumentComplete* complete_response,
NonElidedVector<lsCompletionItem> filtered_result; NonElidedVector<lsCompletionItem> filtered_result;
filtered_result.reserve(kMaxResultSize); filtered_result.reserve(kMaxResultSize);
std::unordered_set<std::string> inserted;
inserted.reserve(kMaxResultSize);
for (const lsCompletionItem& item : complete_response->result.items) { for (const lsCompletionItem& item : complete_response->result.items) {
if (item.label.find(complete_text) != std::string::npos) { if (item.label.find(complete_text) != std::string::npos) {
// Don't insert the same completion entry.
if (!inserted.insert(item.InsertedContent()).second) {
std::cerr << "foo " << item.InsertedContent();
continue;
}
filtered_result.push_back(item); filtered_result.push_back(item);
if (filtered_result.size() >= kMaxResultSize) if (filtered_result.size() >= kMaxResultSize)
break; break;
@ -489,7 +498,10 @@ void FilterCompletionResponse(Out_TextDocumentComplete* complete_response,
if (filtered_result.size() < kMaxResultSize) { if (filtered_result.size() < kMaxResultSize) {
for (const lsCompletionItem& item : complete_response->result.items) { for (const lsCompletionItem& item : complete_response->result.items) {
if (SubstringMatch(complete_text, item.label)) { if (SubstringMatch(complete_text, item.label)) {
//std::cerr << "!! emitting " << item.label << std::endl; // Don't insert the same completion entry.
if (!inserted.insert(item.InsertedContent()).second)
continue;
filtered_result.push_back(item); filtered_result.push_back(item);
if (filtered_result.size() >= kMaxResultSize) if (filtered_result.size() >= kMaxResultSize)
break; break;
@ -2355,8 +2367,16 @@ bool QueryDbMainLoop(
<< " candidates for query " << msg->params.query << std::endl; << " candidates for query " << msg->params.query << std::endl;
std::string query = msg->params.query; std::string query = msg->params.query;
std::unordered_set<std::string> inserted_results;
inserted_results.reserve(config->maxWorkspaceSearchResults);
for (int i = 0; i < db->detailed_names.size(); ++i) { for (int i = 0; i < db->detailed_names.size(); ++i) {
if (db->detailed_names[i].find(query) != std::string::npos) { if (db->detailed_names[i].find(query) != std::string::npos) {
// Do not show the same entry twice.
if (!inserted_results.insert(db->detailed_names[i]).second)
continue;
InsertSymbolIntoResult(db, working_files, db->symbols[i], &response.result); InsertSymbolIntoResult(db, working_files, db->symbols[i], &response.result);
if (response.result.size() >= config->maxWorkspaceSearchResults) if (response.result.size() >= config->maxWorkspaceSearchResults)
break; break;
@ -2366,6 +2386,10 @@ bool QueryDbMainLoop(
if (response.result.size() < config->maxWorkspaceSearchResults) { if (response.result.size() < config->maxWorkspaceSearchResults) {
for (int i = 0; i < db->detailed_names.size(); ++i) { for (int i = 0; i < db->detailed_names.size(); ++i) {
if (SubstringMatch(query, db->detailed_names[i])) { if (SubstringMatch(query, db->detailed_names[i])) {
// Do not show the same entry twice.
if (!inserted_results.insert(db->detailed_names[i]).second)
continue;
InsertSymbolIntoResult(db, working_files, db->symbols[i], &response.result); InsertSymbolIntoResult(db, working_files, db->symbols[i], &response.result);
if (response.result.size() >= config->maxWorkspaceSearchResults) if (response.result.size() >= config->maxWorkspaceSearchResults)
break; break;

View File

@ -215,6 +215,14 @@ bool lsTextEdit::operator==(const lsTextEdit& that) {
return range == that.range && newText == that.newText; return range == that.range && newText == that.newText;
} }
const std::string& lsCompletionItem::InsertedContent() const {
if (textEdit)
return textEdit->newText;
if (!insertText.empty())
return insertText;
return label;
}
void Reflect(Reader& reader, lsInitializeParams::lsTrace& value) { void Reflect(Reader& reader, lsInitializeParams::lsTrace& value) {
std::string v = reader.GetString(); std::string v = reader.GetString();
if (v == "off") if (v == "off")

View File

@ -461,6 +461,11 @@ struct lsCompletionItem {
// An data entry field that is preserved on a completion item between // An data entry field that is preserved on a completion item between
// a completion and a completion resolve request. // a completion and a completion resolve request.
// data ? : any // data ? : any
// Use this helper to figure out what content the completion item will insert
// into the document, as it could live in either |textEdit|, |insertText|, or
// |label|.
const std::string& InsertedContent() const;
}; };
MAKE_REFLECT_STRUCT(lsCompletionItem, MAKE_REFLECT_STRUCT(lsCompletionItem,
label, label,