Jump to the closest symbol and add more lsSymbolKind constants

This commit is contained in:
Fangrui Song 2018-02-13 11:12:08 -08:00
parent 2fab426369
commit 273b670c0d
3 changed files with 33 additions and 15 deletions

View File

@ -6,6 +6,7 @@
#include <ctype.h> #include <ctype.h>
#include <limits.h> #include <limits.h>
#include <cstdlib>
namespace { namespace {
void PushBack(std::vector<lsLocation>* result, optional<lsLocation> location) { void PushBack(std::vector<lsLocation>* result, optional<lsLocation> location) {
@ -129,39 +130,41 @@ struct TextDocumentDefinitionHandler
} }
} }
// Find the best match of the identifier at point. // 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; 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<int, bool, int> best_score = {INT_MAX, true, 0};
int best_i = -1; int best_i = -1;
for (int i = 0; i < (int)db->symbols.size(); ++i) { for (int i = 0; i < (int)db->symbols.size(); ++i) {
if (db->symbols[i].kind == SymbolKind::Invalid) if (db->symbols[i].kind == SymbolKind::Invalid)
continue; continue;
std::string_view detailed_name = db->GetSymbolDetailedName(i); 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) if (idx == std::string::npos)
continue; continue;
Maybe<Use> use = GetDefinitionSpellingOfSymbol(db, db->symbols[i]);
if (!use)
continue;
int score = detailed_name.size() - query.size(); std::tuple<int, bool, int> score = {
assert(score >= 0); int(detailed_name.size() - query.size()), use->file != file_id,
std::abs(use->range.start.line - position.line)};
if (score < best_score) { if (score < best_score) {
best_score = score; best_score = score;
best_i = i; best_i = i;
} }
if (score == 0)
break;
} }
if (best_i != -1) { if (best_i != -1) {
Maybe<Use> use = GetDefinitionSpellingOfSymbol(db, db->symbols[best_i]); Maybe<Use> use = GetDefinitionSpellingOfSymbol(db, db->symbols[best_i]);
if (use) { assert(use);
optional<lsLocation> ls_loc = GetLsLocation(db, working_files, *use); optional<lsLocation> ls_loc = GetLsLocation(db, working_files, *use);
if (ls_loc) if (ls_loc)
out.result.push_back(*ls_loc); out.result.push_back(*ls_loc);
} }
} }
} }
}
QueueManager::WriteStdout(IpcId::TextDocumentDefinition, out); QueueManager::WriteStdout(IpcId::TextDocumentDefinition, out);
} }

View File

@ -510,7 +510,14 @@ optional<lsSymbolInformation> GetSymbolInfo(QueryDatabase* db,
else else
info.name = var.def->detailed_name; info.name = var.def->detailed_name;
info.containerName = var.def->detailed_name; info.containerName = var.def->detailed_name;
switch (var.def->kind) {
default:
info.kind = lsSymbolKind::Variable; info.kind = lsSymbolKind::Variable;
break;
case ClangSymbolKind::EnumConstant:
info.kind = lsSymbolKind::EnumMember;
break;
}
return info; return info;
} }
case SymbolKind::Invalid: case SymbolKind::Invalid:

View File

@ -137,7 +137,15 @@ enum class lsSymbolKind : int {
String = 15, String = 15,
Number = 16, Number = 16,
Boolean = 17, 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); MAKE_REFLECT_TYPE_PROXY(lsSymbolKind);