From 074df673a792ce92a972095803f18749b8d92ea3 Mon Sep 17 00:00:00 2001 From: pommicket Date: Mon, 5 Dec 2022 12:40:13 -0500 Subject: more lsp, start json parser --- lsp.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- main.c | 8 ++++ process-posix.c | 4 ++ process.h | 2 + 4 files changed, 124 insertions(+), 1 deletion(-) diff --git a/lsp.c b/lsp.c index 2c94dfa..c35b691 100644 --- a/lsp.c +++ b/lsp.c @@ -2,7 +2,105 @@ typedef struct { Process process; } LSP; -static void send_message(LSP *lsp, const char *content, size_t content_size) { +typedef struct { + u32 pos; + u32 len; +} JSONString; + +typedef struct JSONValue JSONValue; + +typedef struct { + u32 len; + u32 properties; + u32 values; +} JSONObject; + +typedef struct { + u32 len; + u32 values; +} JSONArray; + +enum { + JSON_NULL, + JSON_FALSE, + JSON_TRUE, + JSON_NUMBER, + JSON_STRING, + JSON_OBJECT, + JSON_ARRAY +}; + +struct JSONValue { + u8 type; + union { + double number; + JSONString string; + JSONArray array; + JSONObject object; + } val; +}; + + +typedef struct { + const char *text; + // root = values[0] + JSONValue *values; +} JSON; + +static bool json_parse_value(JSON *json, u32 *p_index, JSONValue *val) { + const char *text = json->text; + u32 index = *p_index; + while (isspace(text[index])) ++index; + switch (text[index]) { + case '{': + val->type = JSON_OBJECT; + json_parse_object(json, &index, &val->val.object); + break; + case '[': + val->type = JSON_ARRAY; + json_parse_array(json, &index, &val->val.array); + break; + case '"': + val->type = JSON_STRING; + json_parse_string(json, &index, &val->val.string); + break; + case ANY_DIGIT: + json_parse_number(json, &index, &val->val.number); + break; + case 'f': + if (!str_is_prefix(&text[index], "false", 5) != 0) { + + } + } +} + +// NOTE: text must live as long as json!!! +static bool json_parse(JSON *json, const char *text) { + memset(json, 0, sizeof *json); + json->text = text; + // @TODO: is this a good capacity? + arr_reserve(json->values, strlen(text) / 8); + arr_addp(json->values); // add root + JSONValue val = {0}; + u32 index = 0; + if (!json_parse_value(json, &index, &val)) + return false; + + while (isspace(text[index])) ++index; + if (text[index]) { + // more text after end of object + // @TODO error message + return false; + } + json->values[0] = val; +} + +static void send_message(LSP *lsp, const char *content) { + char header[128]; + size_t content_size = strlen(content); + strbuf_printf(header, "Content-Length: %zu\r\n\r\n", content_size); + process_write(&lsp->process, header, strlen(header)); + process_write(&lsp->process, content, content_size); } void lsp_create(LSP *lsp, const char *analyzer_command) { @@ -11,4 +109,15 @@ void lsp_create(LSP *lsp, const char *analyzer_command) { .stdout_blocking = true }; process_run_ex(&lsp->process, analyzer_command, &settings); + char init_request[1024]; + strbuf_printf(init_request, + "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{" + "\"processId\":%d," + "\"capabilities\":{}" + "}}", + process_get_id()); + send_message(lsp, init_request); + char init_response[4096] = {0}; + process_read(&lsp->process, init_response, sizeof init_response); + printf("%s\n",init_response); } diff --git a/main.c b/main.c index dbc49d5..517faaa 100644 --- a/main.c +++ b/main.c @@ -101,6 +101,7 @@ bool tag_goto(Ted *ted, char const *tag); #include "command.c" #include "config.c" #include "session.c" +#include "lsp.c" #if PROFILE #define PROFILE_TIME(var) double var = time_get_seconds(); @@ -279,6 +280,13 @@ int main(int argc, char **argv) { PROFILE_TIME(init_start) PROFILE_TIME(basic_init_start) + // @TODO TEMPORARY + { + LSP lsp={0}; + lsp_create(&lsp, "rust-analyzer"); + exit(0); + } + #if __unix__ { struct sigaction act = {0}; diff --git a/process-posix.c b/process-posix.c index 81c3ff5..1463487 100644 --- a/process-posix.c +++ b/process-posix.c @@ -11,6 +11,10 @@ struct Process { char error[64]; }; +int process_get_id(void) { + return getpid(); +} + bool process_run_ex(Process *proc, const char *command, const ProcessSettings *settings) { memset(proc, 0, sizeof *proc); diff --git a/process.h b/process.h index d8bb6ec..854899b 100644 --- a/process.h +++ b/process.h @@ -10,6 +10,8 @@ typedef struct { bool stdout_blocking; } ProcessSettings; +// get process ID of this process +int process_get_id(void); // execute the given command (like if it was passed to system()). // returns false on failure bool process_run_ex(Process *proc, const char *command, const ProcessSettings *props); -- cgit v1.2.3