mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-26 09:31:59 +00:00
First pass at semantic highlighting.
It is disabled by default.
This commit is contained in:
parent
9d376a47d5
commit
8145a06534
@ -143,6 +143,51 @@ void EmitInactiveLines(WorkingFile* working_file,
|
|||||||
IpcId::CqueryPublishInactiveRegions, out);
|
IpcId::CqueryPublishInactiveRegions, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmitSemanticHighlighting(QueryDatabase* db,
|
||||||
|
WorkingFile* working_file,
|
||||||
|
QueryFile* file) {
|
||||||
|
auto map_symbol_kind_to_symbol_type = [](SymbolKind kind) {
|
||||||
|
switch (kind) {
|
||||||
|
case SymbolKind::Type:
|
||||||
|
return Out_CqueryPublishSemanticHighlighting::SymbolType::Type;
|
||||||
|
case SymbolKind::Func:
|
||||||
|
return Out_CqueryPublishSemanticHighlighting::SymbolType::Function;
|
||||||
|
case SymbolKind::Var:
|
||||||
|
return Out_CqueryPublishSemanticHighlighting::SymbolType::Variable;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
return Out_CqueryPublishSemanticHighlighting::SymbolType::Variable;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Group symbols together.
|
||||||
|
std::unordered_map<SymbolIdx, NonElidedVector<lsRange>> grouped_symbols;
|
||||||
|
for (SymbolRef sym : file->def->all_symbols) {
|
||||||
|
if (sym.idx.kind == SymbolKind::Var) {
|
||||||
|
QueryVar* var = &db->vars[sym.idx.idx];
|
||||||
|
if (!var->def)
|
||||||
|
continue;
|
||||||
|
if (!var->def->is_local)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
optional<lsRange> loc = GetLsRange(working_file, sym.loc.range);
|
||||||
|
if (loc)
|
||||||
|
grouped_symbols[sym.idx].push_back(*loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Publish.
|
||||||
|
Out_CqueryPublishSemanticHighlighting out;
|
||||||
|
out.params.uri = lsDocumentUri::FromPath(working_file->filename);
|
||||||
|
for (auto& entry : grouped_symbols) {
|
||||||
|
Out_CqueryPublishSemanticHighlighting::Symbol symbol;
|
||||||
|
symbol.type = map_symbol_kind_to_symbol_type(entry.first.kind);
|
||||||
|
symbol.ranges = entry.second;
|
||||||
|
out.params.symbols.push_back(symbol);
|
||||||
|
}
|
||||||
|
IpcManager::instance()->SendOutMessageToClient(
|
||||||
|
IpcId::CqueryPublishSemanticHighlighting, out);
|
||||||
|
}
|
||||||
|
|
||||||
optional<int> FindIncludeLine(const std::vector<std::string>& lines,
|
optional<int> FindIncludeLine(const std::vector<std::string>& lines,
|
||||||
const std::string& full_include_line) {
|
const std::string& full_include_line) {
|
||||||
//
|
//
|
||||||
@ -1286,6 +1331,18 @@ bool QueryDb_ImportMain(Config* config,
|
|||||||
return value.path;
|
return value.path;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// Update semantic highlighting.
|
||||||
|
for (auto& updated_file : response->update.files_def_update) {
|
||||||
|
WorkingFile* working_file =
|
||||||
|
working_files->GetFileByFilename(updated_file.path);
|
||||||
|
if (working_file) {
|
||||||
|
QueryFileId file_id =
|
||||||
|
db->usr_to_file[LowerPathIfCaseInsensitive(working_file->filename)];
|
||||||
|
QueryFile* file = &db->files[file_id.id];
|
||||||
|
EmitSemanticHighlighting(db, working_file, file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Mark the files as being done in querydb stage after we apply the index
|
// Mark the files as being done in querydb stage after we apply the index
|
||||||
// update.
|
// update.
|
||||||
for (auto& updated_file : response->update.files_def_update)
|
for (auto& updated_file : response->update.files_def_update)
|
||||||
@ -1774,8 +1831,10 @@ bool QueryDbMainLoop(Config* config,
|
|||||||
|
|
||||||
QueryFile* file = nullptr;
|
QueryFile* file = nullptr;
|
||||||
FindFileOrFail(db, nullopt, path, &file);
|
FindFileOrFail(db, nullopt, path, &file);
|
||||||
if (file && file->def)
|
if (file && file->def) {
|
||||||
EmitInactiveLines(working_file, file->def->inactive_regions);
|
EmitInactiveLines(working_file, file->def->inactive_regions);
|
||||||
|
EmitSemanticHighlighting(db, working_file, file);
|
||||||
|
}
|
||||||
|
|
||||||
time.ResetAndPrint(
|
time.ResetAndPrint(
|
||||||
"[querydb] Loading cached index file for DidOpen (blocks "
|
"[querydb] Loading cached index file for DidOpen (blocks "
|
||||||
@ -2743,8 +2802,11 @@ bool QueryDbMainLoop(Config* config,
|
|||||||
// TODO: We need to move this to a separate request, as the user may
|
// TODO: We need to move this to a separate request, as the user may
|
||||||
// have turned code lens off (ie, a custom DidView notification).
|
// have turned code lens off (ie, a custom DidView notification).
|
||||||
if (file && file->def) {
|
if (file && file->def) {
|
||||||
EmitInactiveLines(working_files->GetFileByFilename(file->def->path),
|
WorkingFile* working_file =
|
||||||
file->def->inactive_regions);
|
working_files->GetFileByFilename(file->def->path);
|
||||||
|
EmitInactiveLines(working_file, file->def->inactive_regions);
|
||||||
|
// Do not emit semantic highlighting information here, as it has not
|
||||||
|
// been updated.
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -51,6 +51,8 @@ const char* IpcIdToString(IpcId id) {
|
|||||||
|
|
||||||
case IpcId::CqueryPublishInactiveRegions:
|
case IpcId::CqueryPublishInactiveRegions:
|
||||||
return "$cquery/publishInactiveRegions";
|
return "$cquery/publishInactiveRegions";
|
||||||
|
case IpcId::CqueryPublishSemanticHighlighting:
|
||||||
|
return "$cquery/publishSemanticHighlighting";
|
||||||
|
|
||||||
case IpcId::CqueryFreshenIndex:
|
case IpcId::CqueryFreshenIndex:
|
||||||
return "$cquery/freshenIndex";
|
return "$cquery/freshenIndex";
|
||||||
|
@ -32,6 +32,7 @@ enum class IpcId : int {
|
|||||||
|
|
||||||
// Custom notifications
|
// Custom notifications
|
||||||
CqueryPublishInactiveRegions,
|
CqueryPublishInactiveRegions,
|
||||||
|
CqueryPublishSemanticHighlighting,
|
||||||
|
|
||||||
// Custom messages
|
// Custom messages
|
||||||
CqueryFreshenIndex,
|
CqueryFreshenIndex,
|
||||||
|
@ -1480,6 +1480,32 @@ struct Out_CquerySetInactiveRegion
|
|||||||
MAKE_REFLECT_STRUCT(Out_CquerySetInactiveRegion::Params, uri, inactiveRegions);
|
MAKE_REFLECT_STRUCT(Out_CquerySetInactiveRegion::Params, uri, inactiveRegions);
|
||||||
MAKE_REFLECT_STRUCT(Out_CquerySetInactiveRegion, jsonrpc, method, params);
|
MAKE_REFLECT_STRUCT(Out_CquerySetInactiveRegion, jsonrpc, method, params);
|
||||||
|
|
||||||
|
struct Out_CqueryPublishSemanticHighlighting
|
||||||
|
: public lsOutMessage<Out_CqueryPublishSemanticHighlighting> {
|
||||||
|
enum class SymbolType { Type = 0, Function, Variable };
|
||||||
|
struct Symbol {
|
||||||
|
SymbolType type;
|
||||||
|
NonElidedVector<lsRange> ranges;
|
||||||
|
};
|
||||||
|
struct Params {
|
||||||
|
lsDocumentUri uri;
|
||||||
|
NonElidedVector<Symbol> symbols;
|
||||||
|
};
|
||||||
|
std::string method = "$cquery/publishSemanticHighlighting";
|
||||||
|
Params params;
|
||||||
|
};
|
||||||
|
MAKE_REFLECT_TYPE_PROXY(Out_CqueryPublishSemanticHighlighting::SymbolType, int);
|
||||||
|
MAKE_REFLECT_STRUCT(Out_CqueryPublishSemanticHighlighting::Symbol,
|
||||||
|
type,
|
||||||
|
ranges);
|
||||||
|
MAKE_REFLECT_STRUCT(Out_CqueryPublishSemanticHighlighting::Params,
|
||||||
|
uri,
|
||||||
|
symbols);
|
||||||
|
MAKE_REFLECT_STRUCT(Out_CqueryPublishSemanticHighlighting,
|
||||||
|
jsonrpc,
|
||||||
|
method,
|
||||||
|
params);
|
||||||
|
|
||||||
struct Ipc_CqueryFreshenIndex : public IpcMessage<Ipc_CqueryFreshenIndex> {
|
struct Ipc_CqueryFreshenIndex : public IpcMessage<Ipc_CqueryFreshenIndex> {
|
||||||
const static IpcId kIpcId = IpcId::CqueryFreshenIndex;
|
const static IpcId kIpcId = IpcId::CqueryFreshenIndex;
|
||||||
lsRequestId id;
|
lsRequestId id;
|
||||||
|
@ -74,6 +74,7 @@ struct SymbolIdx {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(SymbolIdx, kind, idx);
|
MAKE_REFLECT_STRUCT(SymbolIdx, kind, idx);
|
||||||
|
MAKE_HASHABLE(SymbolIdx, t.kind, t.idx);
|
||||||
|
|
||||||
struct SymbolRef {
|
struct SymbolRef {
|
||||||
SymbolIdx idx;
|
SymbolIdx idx;
|
||||||
|
Loading…
Reference in New Issue
Block a user