mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-21 15:15:07 +00:00
Implement textDocument/documentLink
This commit is contained in:
parent
617cdd89de
commit
8fa853c321
@ -222,8 +222,7 @@ target_sources(ccls PRIVATE
|
||||
src/messages/textDocument_did.cc
|
||||
src/messages/textDocument_foldingRange.cc
|
||||
src/messages/textDocument_formatting.cc
|
||||
src/messages/textDocument_documentHighlight.cc
|
||||
src/messages/textDocument_documentSymbol.cc
|
||||
src/messages/textDocument_document.cc
|
||||
src/messages/textDocument_hover.cc
|
||||
src/messages/textDocument_references.cc
|
||||
src/messages/textDocument_rename.cc
|
||||
|
@ -62,12 +62,6 @@ struct lsDocumentOnTypeFormattingOptions {
|
||||
MAKE_REFLECT_STRUCT(lsDocumentOnTypeFormattingOptions, firstTriggerCharacter,
|
||||
moreTriggerCharacter);
|
||||
|
||||
// Document link options
|
||||
struct lsDocumentLinkOptions {
|
||||
// Document links have a resolve provider as well.
|
||||
bool resolveProvider = false;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(lsDocumentLinkOptions, resolveProvider);
|
||||
|
||||
// Save options.
|
||||
struct lsSaveOptions {
|
||||
@ -132,34 +126,22 @@ struct lsServerCapabilities {
|
||||
lsCompletionOptions completionProvider;
|
||||
// The server provides signature help support.
|
||||
lsSignatureHelpOptions signatureHelpProvider;
|
||||
// The server provides goto definition support.
|
||||
bool definitionProvider = true;
|
||||
// The server provides Goto Type Definition support.
|
||||
bool typeDefinitionProvider = true;
|
||||
// The server provides Goto Implementation support.
|
||||
bool implementationProvider = true;
|
||||
// The server provides find references support.
|
||||
bool referencesProvider = true;
|
||||
// The server provides document highlight support.
|
||||
bool documentHighlightProvider = true;
|
||||
// The server provides document symbol support.
|
||||
bool documentSymbolProvider = true;
|
||||
// The server provides workspace symbol support.
|
||||
bool workspaceSymbolProvider = true;
|
||||
// The server provides code actions.
|
||||
bool codeActionProvider = true;
|
||||
// The server provides code lens.
|
||||
lsCodeLensOptions codeLensProvider;
|
||||
// The server provides document formatting.
|
||||
bool documentFormattingProvider = true;
|
||||
// The server provides document range formatting.
|
||||
bool documentRangeFormattingProvider = true;
|
||||
// The server provides document formatting on typing.
|
||||
lsDocumentOnTypeFormattingOptions documentOnTypeFormattingProvider;
|
||||
// The server provides rename support.
|
||||
bool renameProvider = true;
|
||||
// The server provides document link support.
|
||||
lsDocumentLinkOptions documentLinkProvider;
|
||||
struct DocumentLinkOptions {
|
||||
bool resolveProvider = true;
|
||||
} documentLinkProvider;
|
||||
bool foldingRangeProvider = true;
|
||||
// The server provides execute command support.
|
||||
struct ExecuteCommandOptions {
|
||||
@ -172,6 +154,7 @@ struct lsServerCapabilities {
|
||||
} workspaceFolders;
|
||||
} workspace;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(lsServerCapabilities::DocumentLinkOptions, resolveProvider);
|
||||
MAKE_REFLECT_STRUCT(lsServerCapabilities::ExecuteCommandOptions, commands);
|
||||
MAKE_REFLECT_STRUCT(lsServerCapabilities::Workspace::WorkspaceFolders,
|
||||
supported, changeNotifications);
|
||||
|
@ -4,16 +4,116 @@
|
||||
#include "message_handler.h"
|
||||
#include "pipeline.hh"
|
||||
#include "query_utils.h"
|
||||
using namespace ccls;
|
||||
using namespace clang;
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
MAKE_HASHABLE(SymbolIdx, t.usr, t.kind);
|
||||
|
||||
namespace ccls {
|
||||
namespace {
|
||||
MethodType kMethodType = "textDocument/documentSymbol";
|
||||
MethodType documentHighlight = "textDocument/documentHighlight",
|
||||
documentLink = "textDocument/documentLink",
|
||||
documentSymbol = "textDocument/documentSymbol";
|
||||
|
||||
struct In_TextDocumentDocumentSymbol : public RequestMessage {
|
||||
MethodType GetMethodType() const override { return kMethodType; }
|
||||
struct lsDocumentHighlight {
|
||||
enum Kind { Text = 1, Read = 2, Write = 3 };
|
||||
|
||||
lsRange range;
|
||||
int kind = 1;
|
||||
|
||||
// ccls extension
|
||||
Role role = Role::None;
|
||||
|
||||
bool operator<(const lsDocumentHighlight &o) const {
|
||||
return !(range == o.range) ? range < o.range : kind < o.kind;
|
||||
}
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(lsDocumentHighlight, range, kind, role);
|
||||
|
||||
struct In_TextDocumentDocumentHighlight : public RequestMessage {
|
||||
MethodType GetMethodType() const override { return documentHighlight; }
|
||||
lsTextDocumentPositionParams params;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(In_TextDocumentDocumentHighlight, id, params);
|
||||
REGISTER_IN_MESSAGE(In_TextDocumentDocumentHighlight);
|
||||
|
||||
struct Handler_TextDocumentDocumentHighlight
|
||||
: BaseMessageHandler<In_TextDocumentDocumentHighlight> {
|
||||
MethodType GetMethodType() const override { return documentHighlight; }
|
||||
void Run(In_TextDocumentDocumentHighlight *request) override {
|
||||
int file_id;
|
||||
QueryFile *file;
|
||||
if (!FindFileOrFail(db, project, request->id,
|
||||
request->params.textDocument.uri.GetPath(), &file,
|
||||
&file_id))
|
||||
return;
|
||||
|
||||
WorkingFile *wfile = working_files->GetFileByFilename(file->def->path);
|
||||
std::vector<lsDocumentHighlight> result;
|
||||
|
||||
std::vector<SymbolRef> syms =
|
||||
FindSymbolsAtLocation(wfile, file, request->params.position, true);
|
||||
for (auto [sym, refcnt] : file->symbol2refcnt) {
|
||||
if (refcnt <= 0)
|
||||
continue;
|
||||
Usr usr = sym.usr;
|
||||
SymbolKind kind = sym.kind;
|
||||
if (std::none_of(syms.begin(), syms.end(), [&](auto &sym1) {
|
||||
return usr == sym1.usr && kind == sym1.kind;
|
||||
}))
|
||||
continue;
|
||||
if (auto loc = GetLsLocation(db, working_files, sym, file_id)) {
|
||||
lsDocumentHighlight highlight;
|
||||
highlight.range = loc->range;
|
||||
if (sym.role & Role::Write)
|
||||
highlight.kind = lsDocumentHighlight::Write;
|
||||
else if (sym.role & Role::Read)
|
||||
highlight.kind = lsDocumentHighlight::Read;
|
||||
else
|
||||
highlight.kind = lsDocumentHighlight::Text;
|
||||
highlight.role = sym.role;
|
||||
result.push_back(highlight);
|
||||
}
|
||||
}
|
||||
std::sort(result.begin(), result.end());
|
||||
pipeline::Reply(request->id, result);
|
||||
}
|
||||
};
|
||||
REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDocumentHighlight);
|
||||
|
||||
struct In_textDocumentDocumentLink : public RequestMessage {
|
||||
MethodType GetMethodType() const override { return documentLink; }
|
||||
lsTextDocumentPositionParams params;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(In_textDocumentDocumentLink, id, params);
|
||||
REGISTER_IN_MESSAGE(In_textDocumentDocumentLink);
|
||||
|
||||
struct lsDocumentLink {
|
||||
lsRange range;
|
||||
lsDocumentUri target;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(lsDocumentLink, range, target);
|
||||
|
||||
struct Handler_textDocumentDocumentLink
|
||||
: BaseMessageHandler<In_textDocumentDocumentLink> {
|
||||
MethodType GetMethodType() const override { return documentLink; }
|
||||
void Run(In_textDocumentDocumentLink *request) override {
|
||||
QueryFile *file;
|
||||
if (!FindFileOrFail(db, project, request->id,
|
||||
request->params.textDocument.uri.GetPath(), &file))
|
||||
return;
|
||||
|
||||
std::vector<lsDocumentLink> result;
|
||||
for (const IndexInclude &include : file->def->includes)
|
||||
result.push_back({lsRange{{include.line, 0}, {include.line + 1, 0}},
|
||||
lsDocumentUri::FromPath(include.resolved_path)});
|
||||
pipeline::Reply(request->id, result);
|
||||
}
|
||||
};
|
||||
REGISTER_MESSAGE_HANDLER(Handler_textDocumentDocumentLink);
|
||||
|
||||
struct In_textDocumentDocumentSymbol : public RequestMessage {
|
||||
MethodType GetMethodType() const override { return documentSymbol; }
|
||||
struct Params {
|
||||
lsTextDocumentIdentifier textDocument;
|
||||
// false: outline; true: all symbols
|
||||
@ -23,10 +123,10 @@ struct In_TextDocumentDocumentSymbol : public RequestMessage {
|
||||
int endLine = -1;
|
||||
} params;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(In_TextDocumentDocumentSymbol::Params, textDocument, all,
|
||||
MAKE_REFLECT_STRUCT(In_textDocumentDocumentSymbol::Params, textDocument, all,
|
||||
startLine, endLine);
|
||||
MAKE_REFLECT_STRUCT(In_TextDocumentDocumentSymbol, id, params);
|
||||
REGISTER_IN_MESSAGE(In_TextDocumentDocumentSymbol);
|
||||
MAKE_REFLECT_STRUCT(In_textDocumentDocumentSymbol, id, params);
|
||||
REGISTER_IN_MESSAGE(In_textDocumentDocumentSymbol);
|
||||
|
||||
struct lsDocumentSymbol {
|
||||
std::string name;
|
||||
@ -56,10 +156,10 @@ bool Ignore(const QueryVar::Def *def) {
|
||||
return !def || def->is_local();
|
||||
}
|
||||
|
||||
struct Handler_TextDocumentDocumentSymbol
|
||||
: BaseMessageHandler<In_TextDocumentDocumentSymbol> {
|
||||
MethodType GetMethodType() const override { return kMethodType; }
|
||||
void Run(In_TextDocumentDocumentSymbol *request) override {
|
||||
struct Handler_textDocumentDocumentSymbol
|
||||
: BaseMessageHandler<In_textDocumentDocumentSymbol> {
|
||||
MethodType GetMethodType() const override { return documentSymbol; }
|
||||
void Run(In_textDocumentDocumentSymbol *request) override {
|
||||
auto ¶ms = request->params;
|
||||
|
||||
QueryFile *file;
|
||||
@ -180,5 +280,6 @@ struct Handler_TextDocumentDocumentSymbol
|
||||
}
|
||||
}
|
||||
};
|
||||
REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDocumentSymbol);
|
||||
REGISTER_MESSAGE_HANDLER(Handler_textDocumentDocumentSymbol);
|
||||
} // namespace
|
||||
} // namespace ccls
|
@ -1,79 +0,0 @@
|
||||
// Copyright 2017-2018 ccls Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "message_handler.h"
|
||||
#include "pipeline.hh"
|
||||
#include "query_utils.h"
|
||||
|
||||
#include <algorithm>
|
||||
using namespace ccls;
|
||||
|
||||
namespace {
|
||||
MethodType kMethodType = "textDocument/documentHighlight";
|
||||
|
||||
struct lsDocumentHighlight {
|
||||
enum Kind { Text = 1, Read = 2, Write = 3 };
|
||||
|
||||
lsRange range;
|
||||
int kind = 1;
|
||||
|
||||
// ccls extension
|
||||
Role role = Role::None;
|
||||
|
||||
bool operator<(const lsDocumentHighlight &o) const {
|
||||
return !(range == o.range) ? range < o.range : kind < o.kind;
|
||||
}
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(lsDocumentHighlight, range, kind, role);
|
||||
|
||||
struct In_TextDocumentDocumentHighlight : public RequestMessage {
|
||||
MethodType GetMethodType() const override { return kMethodType; }
|
||||
lsTextDocumentPositionParams params;
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(In_TextDocumentDocumentHighlight, id, params);
|
||||
REGISTER_IN_MESSAGE(In_TextDocumentDocumentHighlight);
|
||||
|
||||
struct Handler_TextDocumentDocumentHighlight
|
||||
: BaseMessageHandler<In_TextDocumentDocumentHighlight> {
|
||||
MethodType GetMethodType() const override { return kMethodType; }
|
||||
void Run(In_TextDocumentDocumentHighlight *request) override {
|
||||
int file_id;
|
||||
QueryFile *file;
|
||||
if (!FindFileOrFail(db, project, request->id,
|
||||
request->params.textDocument.uri.GetPath(), &file,
|
||||
&file_id))
|
||||
return;
|
||||
|
||||
WorkingFile *wfile = working_files->GetFileByFilename(file->def->path);
|
||||
std::vector<lsDocumentHighlight> result;
|
||||
|
||||
std::vector<SymbolRef> syms =
|
||||
FindSymbolsAtLocation(wfile, file, request->params.position, true);
|
||||
for (auto [sym, refcnt] : file->symbol2refcnt) {
|
||||
if (refcnt <= 0)
|
||||
continue;
|
||||
Usr usr = sym.usr;
|
||||
SymbolKind kind = sym.kind;
|
||||
if (std::none_of(syms.begin(), syms.end(), [&](auto &sym1) {
|
||||
return usr == sym1.usr && kind == sym1.kind;
|
||||
}))
|
||||
continue;
|
||||
if (auto loc = GetLsLocation(db, working_files, sym, file_id)) {
|
||||
lsDocumentHighlight highlight;
|
||||
highlight.range = loc->range;
|
||||
if (sym.role & Role::Write)
|
||||
highlight.kind = lsDocumentHighlight::Write;
|
||||
else if (sym.role & Role::Read)
|
||||
highlight.kind = lsDocumentHighlight::Read;
|
||||
else
|
||||
highlight.kind = lsDocumentHighlight::Text;
|
||||
highlight.role = sym.role;
|
||||
result.push_back(highlight);
|
||||
}
|
||||
}
|
||||
std::sort(result.begin(), result.end());
|
||||
pipeline::Reply(request->id, result);
|
||||
}
|
||||
};
|
||||
REGISTER_MESSAGE_HANDLER(Handler_TextDocumentDocumentHighlight);
|
||||
} // namespace
|
Loading…
Reference in New Issue
Block a user