summaryrefslogtreecommitdiff
path: root/src/lsp/json_rpc.c
diff options
context:
space:
mode:
authorZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-16 12:43:51 +0000
committerZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-16 12:43:51 +0000
commite77725b55190b8ec6dcab46aa137c32652ea004b (patch)
treea80e237f1f65873f908f5819488c1c32683aff74 /src/lsp/json_rpc.c
parent2e1aa3d8853f3b49e93b1d50b1b6e60e8238d79c (diff)
Support for 'alias' + test. Improved formatting and '.gitignore'.
Diffstat (limited to 'src/lsp/json_rpc.c')
-rw-r--r--src/lsp/json_rpc.c283
1 files changed, 160 insertions, 123 deletions
diff --git a/src/lsp/json_rpc.c b/src/lsp/json_rpc.c
index c75af95..903da71 100644
--- a/src/lsp/json_rpc.c
+++ b/src/lsp/json_rpc.c
@@ -5,81 +5,107 @@
#include <string.h>
// Basic JSON parsing helpers
-char *get_json_string(const char *json, const char *key) {
- char search[256];
- sprintf(search, "\"%s\":\"", key);
- char *p = strstr(json, search);
- if (!p) {
- return NULL;
- }
- p += strlen(search);
- char *end = strchr(p, '"');
- if (!end) {
- return NULL;
- }
- int len = end - p;
- char *res = malloc(len + 1);
- strncpy(res, p, len);
- res[len] = 0;
- return res;
+char *get_json_string(const char *json, const char *key)
+{
+ char search[256];
+ sprintf(search, "\"%s\":\"", key);
+ char *p = strstr(json, search);
+ if (!p)
+ {
+ return NULL;
+ }
+ p += strlen(search);
+ char *end = strchr(p, '"');
+ if (!end)
+ {
+ return NULL;
+ }
+ int len = end - p;
+ char *res = malloc(len + 1);
+ strncpy(res, p, len);
+ res[len] = 0;
+ return res;
}
// Extract nested "text" from params/contentChanges/0/text or
// params/textDocument/text This is very hacky for MVP. proper JSON library
// needed.
-char *get_text_content(const char *json) {
- char *p = strstr(json, "\"text\":\"");
- if (!p) {
- return NULL;
- }
- p += 8;
-
- size_t cap = strlen(p);
- char *res = malloc(cap + 1);
- char *dst = res;
-
- while (*p) {
- if (*p == '\\') {
- p++;
- if (*p == 'n') {
- *dst++ = '\n';
- } else if (*p == 'r') {
- *dst++ = '\r';
- } else if (*p == 't') {
- *dst++ = '\t';
- } else if (*p == '"') {
- *dst++ = '"';
- } else if (*p == '\\') {
- *dst++ = '\\';
- } else {
- *dst++ = *p; // preserve others
- }
- p++;
- } else if (*p == '"') {
- break; // End of string.
- } else {
- *dst++ = *p++;
+char *get_text_content(const char *json)
+{
+ char *p = strstr(json, "\"text\":\"");
+ if (!p)
+ {
+ return NULL;
+ }
+ p += 8;
+
+ size_t cap = strlen(p);
+ char *res = malloc(cap + 1);
+ char *dst = res;
+
+ while (*p)
+ {
+ if (*p == '\\')
+ {
+ p++;
+ if (*p == 'n')
+ {
+ *dst++ = '\n';
+ }
+ else if (*p == 'r')
+ {
+ *dst++ = '\r';
+ }
+ else if (*p == 't')
+ {
+ *dst++ = '\t';
+ }
+ else if (*p == '"')
+ {
+ *dst++ = '"';
+ }
+ else if (*p == '\\')
+ {
+ *dst++ = '\\';
+ }
+ else
+ {
+ *dst++ = *p; // preserve others
+ }
+ p++;
+ }
+ else if (*p == '"')
+ {
+ break; // End of string.
+ }
+ else
+ {
+ *dst++ = *p++;
+ }
}
- }
- *dst = 0;
- return res;
+ *dst = 0;
+ return res;
}
// Helper to get line/char
-void get_json_position(const char *json, int *line, int *col) {
- char *pos = strstr(json, "\"position\":");
- if (!pos) {
- return;
- }
- char *l = strstr(pos, "\"line\":");
- if (l) {
- *line = atoi(l + 7);
- }
- char *c = strstr(pos, "\"character\":");
- if (c) {
- *col = atoi(c + 12);
- }
+void get_json_position(const char *json, int *line, int *col)
+{
+ char *pos = strstr(json, "\"position\":");
+ if (!pos)
+ {
+ return;
+ }
+ char *l = strstr(pos, "\"line\":");
+ if (l)
+ {
+ *line = atoi(l + 7);
+ }
+ char *c = strstr(pos, "\"character\":");
+ if (c)
+ {
+ *col = atoi(c + 12);
+ }
}
void lsp_check_file(const char *uri, const char *src);
@@ -87,71 +113,82 @@ void lsp_goto_definition(const char *uri, int line, int col);
void lsp_hover(const char *uri, int line, int col);
void lsp_completion(const char *uri, int line, int col);
-void handle_request(const char *json_str) {
- if (strstr(json_str, "\"method\":\"initialize\"")) {
- const char *response = "{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":{"
- "\"capabilities\":{\"textDocumentSync\":1,"
- "\"definitionProvider\":true,\"hoverProvider\":true,"
- "\"completionProvider\":{"
- "\"triggerCharacters\":[\".\"]}}}}";
- fprintf(stdout, "Content-Length: %ld\r\n\r\n%s", strlen(response),
- response);
- fflush(stdout);
- return;
- }
-
- if (strstr(json_str, "\"method\":\"textDocument/didOpen\"") ||
- strstr(json_str, "\"method\":\"textDocument/didChange\"")) {
-
- char *uri = get_json_string(json_str, "uri");
- char *text = get_text_content(json_str);
-
- if (uri && text) {
- fprintf(stderr, "zls: Checking %s\n", uri);
- lsp_check_file(uri, text);
+void handle_request(const char *json_str)
+{
+ if (strstr(json_str, "\"method\":\"initialize\""))
+ {
+ const char *response = "{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":{"
+ "\"capabilities\":{\"textDocumentSync\":1,"
+ "\"definitionProvider\":true,\"hoverProvider\":true,"
+ "\"completionProvider\":{"
+ "\"triggerCharacters\":[\".\"]}}}}";
+ fprintf(stdout, "Content-Length: %ld\r\n\r\n%s", strlen(response), response);
+ fflush(stdout);
+ return;
}
- if (uri) {
- free(uri);
- }
- if (text) {
- free(text);
+ if (strstr(json_str, "\"method\":\"textDocument/didOpen\"") ||
+ strstr(json_str, "\"method\":\"textDocument/didChange\""))
+ {
+
+ char *uri = get_json_string(json_str, "uri");
+ char *text = get_text_content(json_str);
+
+ if (uri && text)
+ {
+ fprintf(stderr, "zls: Checking %s\n", uri);
+ lsp_check_file(uri, text);
+ }
+
+ if (uri)
+ {
+ free(uri);
+ }
+ if (text)
+ {
+ free(text);
+ }
}
- }
-
- if (strstr(json_str, "\"method\":\"textDocument/definition\"")) {
- char *uri = get_json_string(json_str, "uri");
- int line = 0, col = 0;
- get_json_position(json_str, &line, &col);
- if (uri) {
- fprintf(stderr, "zls: Definition request at %d:%d\n", line, col);
- lsp_goto_definition(uri, line, col);
- free(uri);
+ if (strstr(json_str, "\"method\":\"textDocument/definition\""))
+ {
+ char *uri = get_json_string(json_str, "uri");
+ int line = 0, col = 0;
+ get_json_position(json_str, &line, &col);
+
+ if (uri)
+ {
+ fprintf(stderr, "zls: Definition request at %d:%d\n", line, col);
+ lsp_goto_definition(uri, line, col);
+ free(uri);
+ }
}
- }
- if (strstr(json_str, "\"method\":\"textDocument/hover\"")) {
- char *uri = get_json_string(json_str, "uri");
- int line = 0, col = 0;
- get_json_position(json_str, &line, &col);
-
- if (uri) {
- fprintf(stderr, "zls: Hover request at %d:%d\n", line, col);
- lsp_hover(uri, line, col);
- free(uri);
+ if (strstr(json_str, "\"method\":\"textDocument/hover\""))
+ {
+ char *uri = get_json_string(json_str, "uri");
+ int line = 0, col = 0;
+ get_json_position(json_str, &line, &col);
+
+ if (uri)
+ {
+ fprintf(stderr, "zls: Hover request at %d:%d\n", line, col);
+ lsp_hover(uri, line, col);
+ free(uri);
+ }
}
- }
-
- if (strstr(json_str, "\"method\":\"textDocument/completion\"")) {
- char *uri = get_json_string(json_str, "uri");
- int line = 0, col = 0;
- get_json_position(json_str, &line, &col);
- if (uri) {
- fprintf(stderr, "zls: Completion request at %d:%d\n", line, col);
- lsp_completion(uri, line, col);
- free(uri);
+ if (strstr(json_str, "\"method\":\"textDocument/completion\""))
+ {
+ char *uri = get_json_string(json_str, "uri");
+ int line = 0, col = 0;
+ get_json_position(json_str, &line, &col);
+
+ if (uri)
+ {
+ fprintf(stderr, "zls: Completion request at %d:%d\n", line, col);
+ lsp_completion(uri, line, col);
+ free(uri);
+ }
}
- }
}