mirror of
https://github.com/MaskRay/ccls.git
synced 2025-01-31 09:50:26 +00:00
Implement textDocument/documentHighlight
This commit is contained in:
parent
20bf746ee9
commit
71d1b1ffc6
@ -538,6 +538,7 @@ std::unique_ptr<IpcMessageQueue> BuildIpcMessageQueue(const std::string& name, s
|
||||
RegisterId<Ipc_TextDocumentDidSave>(ipc.get());
|
||||
RegisterId<Ipc_TextDocumentComplete>(ipc.get());
|
||||
RegisterId<Ipc_TextDocumentDefinition>(ipc.get());
|
||||
RegisterId<Ipc_TextDocumentDocumentHighlight>(ipc.get());
|
||||
RegisterId<Ipc_TextDocumentHover>(ipc.get());
|
||||
RegisterId<Ipc_TextDocumentReferences>(ipc.get());
|
||||
RegisterId<Ipc_TextDocumentDocumentSymbol>(ipc.get());
|
||||
@ -561,6 +562,7 @@ void RegisterMessageTypes() {
|
||||
MessageRegistry::instance()->Register<Ipc_TextDocumentDidSave>();
|
||||
MessageRegistry::instance()->Register<Ipc_TextDocumentComplete>();
|
||||
MessageRegistry::instance()->Register<Ipc_TextDocumentDefinition>();
|
||||
MessageRegistry::instance()->Register<Ipc_TextDocumentDocumentHighlight>();
|
||||
MessageRegistry::instance()->Register<Ipc_TextDocumentHover>();
|
||||
MessageRegistry::instance()->Register<Ipc_TextDocumentReferences>();
|
||||
MessageRegistry::instance()->Register<Ipc_TextDocumentDocumentSymbol>();
|
||||
@ -918,6 +920,49 @@ void QueryDbMainLoop(
|
||||
break;
|
||||
}
|
||||
|
||||
case IpcId::TextDocumentDocumentHighlight: {
|
||||
auto msg = static_cast<Ipc_TextDocumentDocumentHighlight*>(message.get());
|
||||
|
||||
QueryFileId file_id;
|
||||
QueryableFile* file = FindFile(db, msg->params.textDocument.uri.GetPath(), &file_id);
|
||||
if (!file) {
|
||||
std::cerr << "Unable to find file " << msg->params.textDocument.uri.GetPath() << std::endl;
|
||||
break;
|
||||
}
|
||||
Out_TextDocumentDocumentHighlight response;
|
||||
response.id = msg->id;
|
||||
|
||||
// TODO: consider refactoring into FindSymbolsAtLocation(file);
|
||||
int target_line = msg->params.position.line + 1;
|
||||
int target_column = msg->params.position.character + 1;
|
||||
for (const SymbolRef& ref : file->def.all_symbols) {
|
||||
if (ref.loc.range.start.line >= target_line && ref.loc.range.end.line <= target_line &&
|
||||
ref.loc.range.start.column <= target_column && ref.loc.range.end.column >= target_column) {
|
||||
|
||||
// Found symbol. Return references to highlight.
|
||||
std::vector<QueryableLocation> uses = GetUsesOfSymbol(db, ref.idx);
|
||||
response.result.reserve(uses.size());
|
||||
for (const QueryableLocation& use : uses) {
|
||||
if (use.path != file_id)
|
||||
continue;
|
||||
|
||||
optional<lsLocation> ls_location = GetLsLocation(db, working_files, use);
|
||||
if (!ls_location)
|
||||
continue;
|
||||
|
||||
lsDocumentHighlight highlight;
|
||||
highlight.kind = lsDocumentHighlightKind::Text;
|
||||
highlight.range = ls_location->range;
|
||||
response.result.push_back(highlight);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SendOutMessageToClient(language_client, response);
|
||||
break;
|
||||
}
|
||||
|
||||
case IpcId::TextDocumentHover: {
|
||||
auto msg = static_cast<Ipc_TextDocumentHover*>(message.get());
|
||||
|
||||
@ -929,13 +974,14 @@ void QueryDbMainLoop(
|
||||
Out_TextDocumentHover response;
|
||||
response.id = msg->id;
|
||||
|
||||
// TODO: consider refactoring into FindSymbolsAtLocation(file);
|
||||
int target_line = msg->params.position.line + 1;
|
||||
int target_column = msg->params.position.character + 1;
|
||||
for (const SymbolRef& ref : file->def.all_symbols) {
|
||||
if (ref.loc.range.start.line >= target_line && ref.loc.range.end.line <= target_line &&
|
||||
ref.loc.range.start.column <= target_column && ref.loc.range.end.column >= target_column) {
|
||||
|
||||
// Found symbol. Return references.
|
||||
// Found symbol. Return hover.
|
||||
optional<lsRange> ls_range = GetLsRange(working_files->GetFileByFilename(file->def.usr), ref.loc.range);
|
||||
if (!ls_range)
|
||||
continue;
|
||||
@ -1282,8 +1328,8 @@ void LanguageServerStdinLoop(IpcMessageQueue* ipc) {
|
||||
response.result.capabilities.codeLensProvider->resolveProvider = false;
|
||||
|
||||
response.result.capabilities.definitionProvider = true;
|
||||
response.result.capabilities.documentHighlightProvider = true;
|
||||
response.result.capabilities.hoverProvider = true;
|
||||
|
||||
response.result.capabilities.referencesProvider = true;
|
||||
|
||||
response.result.capabilities.documentSymbolProvider = true;
|
||||
@ -1310,6 +1356,7 @@ void LanguageServerStdinLoop(IpcMessageQueue* ipc) {
|
||||
case IpcId::TextDocumentDidSave:
|
||||
case IpcId::TextDocumentCompletion:
|
||||
case IpcId::TextDocumentDefinition:
|
||||
case IpcId::TextDocumentDocumentHighlight:
|
||||
case IpcId::TextDocumentHover:
|
||||
case IpcId::TextDocumentReferences:
|
||||
case IpcId::TextDocumentDocumentSymbol:
|
||||
|
@ -50,6 +50,10 @@ bool operator==(const Id<T>& a, const Id<T>& b) {
|
||||
assert(a.group == b.group && "Cannot compare Ids from different groups");
|
||||
return a.id == b.id;
|
||||
}
|
||||
template <typename T>
|
||||
bool operator!=(const Id<T>& a, const Id<T>& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
using IndexTypeId = Id<IndexedTypeDef>;
|
||||
using IndexFuncId = Id<IndexedFuncDef>;
|
||||
|
@ -22,6 +22,8 @@ const char* IpcIdToString(IpcId id) {
|
||||
return "textDocument/completion";
|
||||
case IpcId::TextDocumentDefinition:
|
||||
return "textDocument/definition";
|
||||
case IpcId::TextDocumentDocumentHighlight:
|
||||
return "textDocument/documentHighlight";
|
||||
case IpcId::TextDocumentHover:
|
||||
return "textDocument/hover";
|
||||
case IpcId::TextDocumentReferences:
|
||||
|
@ -16,6 +16,7 @@ enum class IpcId : int {
|
||||
TextDocumentDidSave,
|
||||
TextDocumentCompletion,
|
||||
TextDocumentDefinition,
|
||||
TextDocumentDocumentHighlight,
|
||||
TextDocumentHover,
|
||||
TextDocumentReferences,
|
||||
TextDocumentDocumentSymbol,
|
||||
|
@ -166,6 +166,11 @@ std::string lsDocumentUri::GetPath() const {
|
||||
}
|
||||
|
||||
std::replace(result.begin(), result.end(), '\\', '/');
|
||||
|
||||
#if defined(_WIN32)
|
||||
//std::transform(result.begin(), result.end(), result.begin(), ::tolower);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -488,6 +488,29 @@ struct lsTextDocumentEdit {
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(lsTextDocumentEdit, textDocument, edits);
|
||||
|
||||
// A document highlight kind.
|
||||
enum class lsDocumentHighlightKind {
|
||||
// A textual occurrence.
|
||||
Text = 1,
|
||||
// Read-access of a symbol, like reading a variable.
|
||||
Read = 2,
|
||||
// Write-access of a symbol, like writing to a variable.
|
||||
Write = 3
|
||||
};
|
||||
MAKE_REFLECT_TYPE_PROXY(lsDocumentHighlightKind, int);
|
||||
|
||||
// A document highlight is a range inside a text document which deserves
|
||||
// special attention. Usually a document highlight is visualized by changing
|
||||
// the background color of its range.
|
||||
struct lsDocumentHighlight {
|
||||
// The range this highlight applies to.
|
||||
lsRange range;
|
||||
|
||||
// The highlight kind, default is DocumentHighlightKind.Text.
|
||||
lsDocumentHighlightKind kind = lsDocumentHighlightKind::Text;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(lsDocumentHighlight, range, kind);
|
||||
|
||||
// TODO: WorkspaceEdit
|
||||
// TODO: DocumentFilter
|
||||
// TODO: DocumentSelector
|
||||
@ -1131,6 +1154,20 @@ struct Out_TextDocumentDefinition : public lsOutMessage<Out_TextDocumentDefiniti
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(Out_TextDocumentDefinition, jsonrpc, id, result);
|
||||
|
||||
// Document highlight
|
||||
struct Ipc_TextDocumentDocumentHighlight : public IpcMessage<Ipc_TextDocumentDocumentHighlight> {
|
||||
const static IpcId kIpcId = IpcId::TextDocumentDocumentHighlight;
|
||||
|
||||
lsRequestId id;
|
||||
lsTextDocumentPositionParams params;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(Ipc_TextDocumentDocumentHighlight, id, params);
|
||||
struct Out_TextDocumentDocumentHighlight : public lsOutMessage<Out_TextDocumentDocumentHighlight> {
|
||||
lsRequestId id;
|
||||
NonElidedVector<lsDocumentHighlight> result;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(Out_TextDocumentDocumentHighlight, jsonrpc, id, result);
|
||||
|
||||
// Hover
|
||||
struct Ipc_TextDocumentHover : public IpcMessage<Ipc_TextDocumentHover> {
|
||||
const static IpcId kIpcId = IpcId::TextDocumentHover;
|
||||
|
@ -141,6 +141,7 @@ std::string NormalizePath(const std::string& path) {
|
||||
|
||||
std::string result = buffer;
|
||||
std::replace(result.begin(), result.end(), '\\', '/');
|
||||
//std::transform(result.begin(), result.end(), result.begin(), ::tolower);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user