Notification support
This commit is contained in:
parent
64db0526ad
commit
297c8f800e
7 changed files with 286 additions and 102 deletions
132
src/pawn_lsp.c
Normal file
132
src/pawn_lsp.c
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cJSON/cJSON.h"
|
||||
#include "json_rpc.h"
|
||||
#include "log.h"
|
||||
#include "pawn_lsp.h"
|
||||
|
||||
#define PAWN_LSP_VESRION "v0.0.1"
|
||||
#define PAWN_LSP_NAME "pawn_lsp"
|
||||
|
||||
|
||||
static int _request_handler(json_rpc_request_t *req, cJSON **resp, void *arg);
|
||||
static void _notify_handler(json_rpc_request_t *req, void *arg);
|
||||
|
||||
static int _initialize(json_rpc_request_t *req, cJSON **resp, void *arg);
|
||||
static int _shutdown(json_rpc_request_t *req, cJSON **resp, void *arg);
|
||||
|
||||
static void _exit_notf(json_rpc_request_t *req, void *arg);
|
||||
|
||||
int
|
||||
pawn_lsp_init(pawn_lsp_t *pawn,
|
||||
json_rpc_t *jrpc,
|
||||
const char *pawncc,
|
||||
char **pawn_args,
|
||||
int pawn_argc)
|
||||
{
|
||||
pawn->jrpc = jrpc;
|
||||
pawn->pawncc = strdup(pawncc);
|
||||
|
||||
/* execv(pawncc <filename> -d0 -v=2 -o/tmp/... [...args] <NULL>)*/
|
||||
pawn->pawn_args = calloc(pawn_argc + 5, sizeof(char *));
|
||||
/* pawn->pawn_args[0] = <filename>, set when compiling */
|
||||
pawn->pawn_args[1] = strdup("-d0");
|
||||
pawn->pawn_args[2] = strdup("-v=2");
|
||||
/* pawn->pawn_args[3] = -o/tmp/..., set when compiling */
|
||||
for (int i = 0; i < pawn_argc; i++) {
|
||||
pawn->pawn_args[i + 4] = strdup(pawn_args[i]);
|
||||
}
|
||||
|
||||
json_rpc_set_request_handler(jrpc, _request_handler, &pawn);
|
||||
json_rpc_set_notify_handler(jrpc, _notify_handler, &pawn);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
pawn_lsp_deinit(pawn_lsp_t *pawn)
|
||||
{
|
||||
free(pawn->pawncc);
|
||||
for (int i = 0; pawn->pawn_args[i] != NULL; i++) {
|
||||
free(pawn->pawn_args[i]);
|
||||
}
|
||||
free(pawn->pawn_args);
|
||||
}
|
||||
|
||||
static int
|
||||
_request_handler(json_rpc_request_t *req, cJSON **resp, void *arg)
|
||||
{
|
||||
char *method = req->method->valuestring;
|
||||
|
||||
log_info("Handle request \"%s\"\r\n", method);
|
||||
|
||||
if (!strcmp(method, "initialize")) {
|
||||
return _initialize(req, resp, arg);
|
||||
} else if (!strcmp(method, "shutdown")) {
|
||||
return _shutdown(req, resp, arg);
|
||||
} else {
|
||||
log_warn("Unrecognized request method\r\n");
|
||||
(*resp) = cJSON_CreateNull();
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_notify_handler(json_rpc_request_t *req, void *arg)
|
||||
{
|
||||
char *method = req->method->valuestring;
|
||||
|
||||
log_info("Handle notification \"%s\"\r\n", method);
|
||||
|
||||
if (!strcmp(method, "exit")) {
|
||||
_exit_notf(req, arg);
|
||||
} else {
|
||||
log_warn("Unrecognized notification method\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_initialize(json_rpc_request_t *req, cJSON **resp, void *arg)
|
||||
{
|
||||
cJSON *val;
|
||||
|
||||
(*resp) = cJSON_CreateObject();
|
||||
|
||||
val = cJSON_AddObjectToObject((*resp), "capabilities");
|
||||
if (val == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (cJSON_AddStringToObject(val, "positionEncoding", "utf-8") == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
val = cJSON_AddObjectToObject((*resp), "serverInfo");
|
||||
if (val == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if ((cJSON_AddStringToObject(val, "name", PAWN_LSP_NAME) == NULL) ||
|
||||
(cJSON_AddStringToObject(val, "version", PAWN_LSP_VESRION) == NULL)) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
_shutdown(json_rpc_request_t *req, cJSON **resp, void *arg)
|
||||
{
|
||||
(*resp) = cJSON_CreateNull();
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
_exit_notf(json_rpc_request_t *req, void *arg)
|
||||
{
|
||||
pawn_lsp_t *pawn = arg;
|
||||
json_rpc_cancel(pawn->jrpc);
|
||||
}
|
||||
|
||||
Loading…
Reference in a new issue