summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lsp.c111
-rw-r--r--main.c8
-rw-r--r--process-posix.c4
-rw-r--r--process.h2
4 files changed, 124 insertions, 1 deletions
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);