diff --git a/src/messages/text_document_definition.cc b/src/messages/text_document_definition.cc index f0b1d3b3..fdeeefb2 100644 --- a/src/messages/text_document_definition.cc +++ b/src/messages/text_document_definition.cc @@ -6,6 +6,7 @@ #include #include +#include namespace { void PushBack(std::vector* result, optional location) { @@ -129,36 +130,38 @@ struct TextDocumentDefinitionHandler } } // Find the best match of the identifier at point. - if (!has_symbol && db->symbols.size()) { + if (!has_symbol) { + lsPosition position = request->params.position; const std::string& buffer = working_file->buffer_content; - std::string query = LexWordAroundPos(request->params.position, buffer); + std::string query = LexWordAroundPos(position, buffer); - int best_score = INT_MAX; + std::tuple best_score = {INT_MAX, true, 0}; int best_i = -1; for (int i = 0; i < (int)db->symbols.size(); ++i) { if (db->symbols[i].kind == SymbolKind::Invalid) continue; std::string_view detailed_name = db->GetSymbolDetailedName(i); - size_t idx = detailed_name.find(query); + auto idx = detailed_name.find(query); if (idx == std::string::npos) continue; + Maybe use = GetDefinitionSpellingOfSymbol(db, db->symbols[i]); + if (!use) + continue; - int score = detailed_name.size() - query.size(); - assert(score >= 0); + std::tuple score = { + int(detailed_name.size() - query.size()), use->file != file_id, + std::abs(use->range.start.line - position.line)}; if (score < best_score) { best_score = score; best_i = i; } - if (score == 0) - break; } if (best_i != -1) { Maybe use = GetDefinitionSpellingOfSymbol(db, db->symbols[best_i]); - if (use) { - optional ls_loc = GetLsLocation(db, working_files, *use); - if (ls_loc) - out.result.push_back(*ls_loc); - } + assert(use); + optional ls_loc = GetLsLocation(db, working_files, *use); + if (ls_loc) + out.result.push_back(*ls_loc); } } } diff --git a/src/query_utils.cc b/src/query_utils.cc index 44155241..cd8e4b16 100644 --- a/src/query_utils.cc +++ b/src/query_utils.cc @@ -510,7 +510,14 @@ optional GetSymbolInfo(QueryDatabase* db, else info.name = var.def->detailed_name; info.containerName = var.def->detailed_name; - info.kind = lsSymbolKind::Variable; + switch (var.def->kind) { + default: + info.kind = lsSymbolKind::Variable; + break; + case ClangSymbolKind::EnumConstant: + info.kind = lsSymbolKind::EnumMember; + break; + } return info; } case SymbolKind::Invalid: diff --git a/src/symbol.h b/src/symbol.h index e8e906a3..ba102640 100644 --- a/src/symbol.h +++ b/src/symbol.h @@ -137,7 +137,15 @@ enum class lsSymbolKind : int { String = 15, Number = 16, Boolean = 17, - Array = 18 + Array = 18, + Object = 19, + Key = 20, + Null = 21, + EnumMember = 22, + Struct = 23, + Event = 24, + Operator = 25, + TypeParameter = 26, }; MAKE_REFLECT_TYPE_PROXY(lsSymbolKind);