mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-22 07:35:08 +00:00
Support the 'reference' codeActionKind
https://github.com/joaotavora/eglot/issues/302#issuecomment-550225329
This commit is contained in:
parent
8b4d0fc055
commit
17b769851f
@ -70,7 +70,7 @@ struct ServerCap {
|
||||
bool documentSymbolProvider = true;
|
||||
bool workspaceSymbolProvider = true;
|
||||
struct CodeActionOptions {
|
||||
std::vector<const char *> codeActionKinds = {"quickfix"};
|
||||
std::vector<const char *> codeActionKinds = {"quickfix", "reference"};
|
||||
} codeActionProvider;
|
||||
struct CodeLensOptions {
|
||||
bool resolveProvider = false;
|
||||
|
@ -14,34 +14,65 @@
|
||||
|
||||
namespace ccls {
|
||||
namespace {
|
||||
struct Command {
|
||||
std::string title;
|
||||
std::string command;
|
||||
std::vector<std::string> arguments;
|
||||
};
|
||||
struct CodeAction {
|
||||
std::string title;
|
||||
const char *kind = "quickfix";
|
||||
std::string kind;
|
||||
WorkspaceEdit edit;
|
||||
Command command;
|
||||
};
|
||||
REFLECT_STRUCT(CodeAction, title, kind, edit);
|
||||
struct ReferenceCommand {
|
||||
TextDocumentIdentifier textDocument;
|
||||
Position position;
|
||||
bool callee;
|
||||
std::string direction;
|
||||
bool derived;
|
||||
int kind;
|
||||
};
|
||||
REFLECT_STRUCT(Command, title, command, arguments);
|
||||
REFLECT_STRUCT(CodeAction, title, kind, edit, command);
|
||||
REFLECT_STRUCT(ReferenceCommand, textDocument, position,
|
||||
callee, direction, derived, kind);
|
||||
|
||||
template <typename T> std::string toString(T &v) {
|
||||
rapidjson::StringBuffer output;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(output);
|
||||
JsonWriter json_writer(&writer);
|
||||
reflect(json_writer, v);
|
||||
return output.GetString();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
template <typename T> bool vec_has(const std::vector<T> &vec, const T &key) {
|
||||
return std::find(std::begin(vec), std::end(vec), key) != std::end(vec);
|
||||
}
|
||||
|
||||
bool should_send_action(std::vector<std::string> available_kinds,
|
||||
std::vector<std::string> requested_kinds,
|
||||
std::string kind) {
|
||||
if (!requested_kinds.empty() && !vec_has(requested_kinds, kind)) {
|
||||
return false;
|
||||
}
|
||||
if (!available_kinds.empty() && !vec_has(available_kinds, kind)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void MessageHandler::textDocument_codeAction(CodeActionParam ¶m,
|
||||
ReplyOnce &reply) {
|
||||
WorkingFile *wf = findOrFail(param.textDocument.uri.getPath(), reply).second;
|
||||
if (!wf)
|
||||
return;
|
||||
std::vector<std::string> only = param.context.only;
|
||||
auto available_kinds = g_config->client.codeActionKind;
|
||||
std::vector<std::string> requested_kinds = param.context.only;
|
||||
std::vector<CodeAction> result;
|
||||
if (!only.empty() && !vec_has(only, std::string("quickfix"))) {
|
||||
reply(result);
|
||||
return;
|
||||
}
|
||||
auto kinds = g_config->client.codeActionKind;
|
||||
if (!kinds.empty() && !vec_has(kinds, std::string("quickfix"))) {
|
||||
reply(result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (should_send_action(available_kinds, requested_kinds, "quickfix")) {
|
||||
std::vector<Diagnostic> diagnostics;
|
||||
wfiles->withLock([&]() { diagnostics = wf->diagnostics; });
|
||||
for (Diagnostic &diag : diagnostics)
|
||||
@ -52,11 +83,48 @@ void MessageHandler::textDocument_codeAction(CodeActionParam ¶m,
|
||||
}))) {
|
||||
CodeAction &cmd = result.emplace_back();
|
||||
cmd.title = "FixIt: " + diag.message;
|
||||
cmd.kind = "quickfix";
|
||||
auto &edit = cmd.edit.documentChanges.emplace_back();
|
||||
edit.textDocument.uri = param.textDocument.uri;
|
||||
edit.textDocument.version = wf->version;
|
||||
edit.edits = diag.fixits_;
|
||||
}
|
||||
}
|
||||
|
||||
if (should_send_action(available_kinds, requested_kinds, "reference")) {
|
||||
auto add = [&, param = param] (
|
||||
const char *title, const char *command_name,
|
||||
const bool callee=false, const char *dir="",
|
||||
const bool derived=false, int kind=0) {
|
||||
CodeAction &cmd = result.emplace_back();
|
||||
ReferenceCommand rcmd;
|
||||
rcmd.textDocument = param.textDocument;
|
||||
rcmd.position = param.range.start;
|
||||
rcmd.callee = callee;
|
||||
rcmd.direction = dir;
|
||||
rcmd.derived = derived;
|
||||
rcmd.kind = kind;
|
||||
cmd.title = title;
|
||||
cmd.kind = "reference";
|
||||
cmd.command.title = title;
|
||||
cmd.command.command = command_name;
|
||||
cmd.command.arguments.push_back(toString(rcmd));
|
||||
};
|
||||
|
||||
add("call", "$ccls/call");
|
||||
add("callee", "$ccls/call", true);
|
||||
add("navigate-up", "$ccls/navigate", false, "U");
|
||||
add("navigate-down", "$ccls/navigate", false, "D");
|
||||
add("navigate-right", "$ccls/navigate", false, "R");
|
||||
add("navigate-left", "$ccls/navigate", false, "L");
|
||||
add("inheritance", "$ccls/inheritance");
|
||||
add("inheritance-derived", "$ccls/inheritance", false, "", true);
|
||||
add("member-var", "$ccls/member", false, "", 4);
|
||||
add("member-fun", "$ccls/member", false, "", 3);
|
||||
add("member-type", "$ccls/member", false, "", 2);
|
||||
add("vars", "$ccls/vars");
|
||||
}
|
||||
|
||||
reply(result);
|
||||
}
|
||||
|
||||
@ -66,27 +134,13 @@ struct Cmd_xref {
|
||||
Kind kind;
|
||||
std::string field;
|
||||
};
|
||||
struct Command {
|
||||
std::string title;
|
||||
std::string command;
|
||||
std::vector<std::string> arguments;
|
||||
};
|
||||
struct CodeLens {
|
||||
lsRange range;
|
||||
std::optional<Command> command;
|
||||
};
|
||||
REFLECT_STRUCT(Cmd_xref, usr, kind, field);
|
||||
REFLECT_STRUCT(Command, title, command, arguments);
|
||||
REFLECT_STRUCT(CodeLens, range, command);
|
||||
|
||||
template <typename T> std::string toString(T &v) {
|
||||
rapidjson::StringBuffer output;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(output);
|
||||
JsonWriter json_writer(&writer);
|
||||
reflect(json_writer, v);
|
||||
return output.GetString();
|
||||
}
|
||||
|
||||
struct CommonCodeLensParams {
|
||||
std::vector<CodeLens> *result;
|
||||
DB *db;
|
||||
@ -230,6 +284,16 @@ void MessageHandler::workspace_executeCommand(JsonReader &reader,
|
||||
break;
|
||||
}
|
||||
reply(result);
|
||||
} else if (param.command == "$ccls/call") {
|
||||
ccls_call(json_reader, reply);
|
||||
} else if (param.command == "$ccls/navigate") {
|
||||
ccls_navigate(json_reader, reply);
|
||||
} else if (param.command == "$ccls/inheritance") {
|
||||
ccls_inheritance(json_reader, reply);
|
||||
} else if (param.command == "$ccls/member") {
|
||||
ccls_member(json_reader, reply);
|
||||
} else if (param.command == "$ccls/vars") {
|
||||
ccls_vars(json_reader, reply);
|
||||
}
|
||||
}
|
||||
} // namespace ccls
|
||||
|
Loading…
Reference in New Issue
Block a user