mirror of
https://github.com/MaskRay/ccls.git
synced 2025-03-31 05:52:09 +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_TextDocumentDidSave>(ipc.get());
|
||||||
RegisterId<Ipc_TextDocumentComplete>(ipc.get());
|
RegisterId<Ipc_TextDocumentComplete>(ipc.get());
|
||||||
RegisterId<Ipc_TextDocumentDefinition>(ipc.get());
|
RegisterId<Ipc_TextDocumentDefinition>(ipc.get());
|
||||||
|
RegisterId<Ipc_TextDocumentDocumentHighlight>(ipc.get());
|
||||||
RegisterId<Ipc_TextDocumentHover>(ipc.get());
|
RegisterId<Ipc_TextDocumentHover>(ipc.get());
|
||||||
RegisterId<Ipc_TextDocumentReferences>(ipc.get());
|
RegisterId<Ipc_TextDocumentReferences>(ipc.get());
|
||||||
RegisterId<Ipc_TextDocumentDocumentSymbol>(ipc.get());
|
RegisterId<Ipc_TextDocumentDocumentSymbol>(ipc.get());
|
||||||
@ -561,6 +562,7 @@ void RegisterMessageTypes() {
|
|||||||
MessageRegistry::instance()->Register<Ipc_TextDocumentDidSave>();
|
MessageRegistry::instance()->Register<Ipc_TextDocumentDidSave>();
|
||||||
MessageRegistry::instance()->Register<Ipc_TextDocumentComplete>();
|
MessageRegistry::instance()->Register<Ipc_TextDocumentComplete>();
|
||||||
MessageRegistry::instance()->Register<Ipc_TextDocumentDefinition>();
|
MessageRegistry::instance()->Register<Ipc_TextDocumentDefinition>();
|
||||||
|
MessageRegistry::instance()->Register<Ipc_TextDocumentDocumentHighlight>();
|
||||||
MessageRegistry::instance()->Register<Ipc_TextDocumentHover>();
|
MessageRegistry::instance()->Register<Ipc_TextDocumentHover>();
|
||||||
MessageRegistry::instance()->Register<Ipc_TextDocumentReferences>();
|
MessageRegistry::instance()->Register<Ipc_TextDocumentReferences>();
|
||||||
MessageRegistry::instance()->Register<Ipc_TextDocumentDocumentSymbol>();
|
MessageRegistry::instance()->Register<Ipc_TextDocumentDocumentSymbol>();
|
||||||
@ -918,6 +920,49 @@ void QueryDbMainLoop(
|
|||||||
break;
|
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: {
|
case IpcId::TextDocumentHover: {
|
||||||
auto msg = static_cast<Ipc_TextDocumentHover*>(message.get());
|
auto msg = static_cast<Ipc_TextDocumentHover*>(message.get());
|
||||||
|
|
||||||
@ -929,13 +974,14 @@ void QueryDbMainLoop(
|
|||||||
Out_TextDocumentHover response;
|
Out_TextDocumentHover response;
|
||||||
response.id = msg->id;
|
response.id = msg->id;
|
||||||
|
|
||||||
|
// TODO: consider refactoring into FindSymbolsAtLocation(file);
|
||||||
int target_line = msg->params.position.line + 1;
|
int target_line = msg->params.position.line + 1;
|
||||||
int target_column = msg->params.position.character + 1;
|
int target_column = msg->params.position.character + 1;
|
||||||
for (const SymbolRef& ref : file->def.all_symbols) {
|
for (const SymbolRef& ref : file->def.all_symbols) {
|
||||||
if (ref.loc.range.start.line >= target_line && ref.loc.range.end.line <= target_line &&
|
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) {
|
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);
|
optional<lsRange> ls_range = GetLsRange(working_files->GetFileByFilename(file->def.usr), ref.loc.range);
|
||||||
if (!ls_range)
|
if (!ls_range)
|
||||||
continue;
|
continue;
|
||||||
@ -1282,8 +1328,8 @@ void LanguageServerStdinLoop(IpcMessageQueue* ipc) {
|
|||||||
response.result.capabilities.codeLensProvider->resolveProvider = false;
|
response.result.capabilities.codeLensProvider->resolveProvider = false;
|
||||||
|
|
||||||
response.result.capabilities.definitionProvider = true;
|
response.result.capabilities.definitionProvider = true;
|
||||||
|
response.result.capabilities.documentHighlightProvider = true;
|
||||||
response.result.capabilities.hoverProvider = true;
|
response.result.capabilities.hoverProvider = true;
|
||||||
|
|
||||||
response.result.capabilities.referencesProvider = true;
|
response.result.capabilities.referencesProvider = true;
|
||||||
|
|
||||||
response.result.capabilities.documentSymbolProvider = true;
|
response.result.capabilities.documentSymbolProvider = true;
|
||||||
@ -1310,6 +1356,7 @@ void LanguageServerStdinLoop(IpcMessageQueue* ipc) {
|
|||||||
case IpcId::TextDocumentDidSave:
|
case IpcId::TextDocumentDidSave:
|
||||||
case IpcId::TextDocumentCompletion:
|
case IpcId::TextDocumentCompletion:
|
||||||
case IpcId::TextDocumentDefinition:
|
case IpcId::TextDocumentDefinition:
|
||||||
|
case IpcId::TextDocumentDocumentHighlight:
|
||||||
case IpcId::TextDocumentHover:
|
case IpcId::TextDocumentHover:
|
||||||
case IpcId::TextDocumentReferences:
|
case IpcId::TextDocumentReferences:
|
||||||
case IpcId::TextDocumentDocumentSymbol:
|
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");
|
assert(a.group == b.group && "Cannot compare Ids from different groups");
|
||||||
return a.id == b.id;
|
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 IndexTypeId = Id<IndexedTypeDef>;
|
||||||
using IndexFuncId = Id<IndexedFuncDef>;
|
using IndexFuncId = Id<IndexedFuncDef>;
|
||||||
|
@ -22,6 +22,8 @@ const char* IpcIdToString(IpcId id) {
|
|||||||
return "textDocument/completion";
|
return "textDocument/completion";
|
||||||
case IpcId::TextDocumentDefinition:
|
case IpcId::TextDocumentDefinition:
|
||||||
return "textDocument/definition";
|
return "textDocument/definition";
|
||||||
|
case IpcId::TextDocumentDocumentHighlight:
|
||||||
|
return "textDocument/documentHighlight";
|
||||||
case IpcId::TextDocumentHover:
|
case IpcId::TextDocumentHover:
|
||||||
return "textDocument/hover";
|
return "textDocument/hover";
|
||||||
case IpcId::TextDocumentReferences:
|
case IpcId::TextDocumentReferences:
|
||||||
|
@ -16,6 +16,7 @@ enum class IpcId : int {
|
|||||||
TextDocumentDidSave,
|
TextDocumentDidSave,
|
||||||
TextDocumentCompletion,
|
TextDocumentCompletion,
|
||||||
TextDocumentDefinition,
|
TextDocumentDefinition,
|
||||||
|
TextDocumentDocumentHighlight,
|
||||||
TextDocumentHover,
|
TextDocumentHover,
|
||||||
TextDocumentReferences,
|
TextDocumentReferences,
|
||||||
TextDocumentDocumentSymbol,
|
TextDocumentDocumentSymbol,
|
||||||
|
@ -166,6 +166,11 @@ std::string lsDocumentUri::GetPath() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::replace(result.begin(), result.end(), '\\', '/');
|
std::replace(result.begin(), result.end(), '\\', '/');
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
//std::transform(result.begin(), result.end(), result.begin(), ::tolower);
|
||||||
|
#endif
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,6 +488,29 @@ struct lsTextDocumentEdit {
|
|||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(lsTextDocumentEdit, textDocument, edits);
|
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: WorkspaceEdit
|
||||||
// TODO: DocumentFilter
|
// TODO: DocumentFilter
|
||||||
// TODO: DocumentSelector
|
// TODO: DocumentSelector
|
||||||
@ -1131,6 +1154,20 @@ struct Out_TextDocumentDefinition : public lsOutMessage<Out_TextDocumentDefiniti
|
|||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(Out_TextDocumentDefinition, jsonrpc, id, result);
|
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
|
// Hover
|
||||||
struct Ipc_TextDocumentHover : public IpcMessage<Ipc_TextDocumentHover> {
|
struct Ipc_TextDocumentHover : public IpcMessage<Ipc_TextDocumentHover> {
|
||||||
const static IpcId kIpcId = IpcId::TextDocumentHover;
|
const static IpcId kIpcId = IpcId::TextDocumentHover;
|
||||||
|
@ -141,6 +141,7 @@ std::string NormalizePath(const std::string& path) {
|
|||||||
|
|
||||||
std::string result = buffer;
|
std::string result = buffer;
|
||||||
std::replace(result.begin(), result.end(), '\\', '/');
|
std::replace(result.begin(), result.end(), '\\', '/');
|
||||||
|
//std::transform(result.begin(), result.end(), result.begin(), ::tolower);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user