Random Stuff

This commit is contained in:
2025-10-03 12:40:47 +01:00
parent a1bddc70dc
commit 508a2f502d
10 changed files with 236 additions and 107 deletions

View File

@@ -3,7 +3,6 @@
#include "constants.h"
#include "helper_functions.h"
#include "node.h"
#include <ctype.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdio.h>
@@ -19,17 +18,6 @@ int lsp_pid = -1;
int version = 1;
int c_id = 1;
pthread_mutex_t lsp_mutex = PTHREAD_MUTEX_INITIALIZER;
typedef enum {
HOVER,
} LspRequestType;
typedef struct LspQueue LspQueue;
typedef struct LspQueue {
LspRequestType type;
int id;
Node *buffer;
struct LspQueue *next;
} LspQueue;
LspQueue *lsp_head = NULL;
void lsp_enqueue(LspRequestType type, int id, Node *buffer) {
@@ -50,73 +38,6 @@ void lsp_enqueue(LspRequestType type, int id, Node *buffer) {
pthread_mutex_unlock(&lsp_mutex);
}
void measure_text(const char *text, int *out_lines, int *out_longest) {
if (!text) {
*out_lines = 0;
*out_longest = 0;
return;
}
char *copy = strdup(text);
if (!copy) {
*out_lines = 0;
*out_longest = 0;
return;
}
int lines = 0;
int longest = 0;
char *line = strtok(copy, "\n");
while (line) {
int len = strlen(line);
if (len > longest)
longest = len;
lines++;
line = strtok(NULL, "\n");
}
free(copy);
*out_lines = lines + 1;
*out_longest = longest;
}
void wrap_text(char *text, int max_width) {
if (!text || max_width <= 0)
return;
int line_length = 0;
char *read_pos = text;
char *write_pos = text;
char *last_space = NULL;
while (*read_pos) {
*write_pos = *read_pos;
if (isspace(*read_pos)) {
if (*read_pos != '\n')
last_space = write_pos;
if (*read_pos == '\n') {
line_length = 0;
last_space = NULL;
} else {
line_length++;
}
} else {
line_length++;
}
if (line_length > max_width) {
if (last_space != NULL) {
*last_space = '\n';
line_length = write_pos - last_space;
last_space = NULL;
} else {
memmove(write_pos + 1, write_pos, strlen(write_pos) + 1);
*write_pos = '\n';
write_pos++;
line_length = 1;
}
}
read_pos++;
write_pos++;
}
}
void send_notification(cJSON *msg);
void handle_hover_response(Node *buffer, cJSON *msg) {
cJSON *result = cJSON_GetObjectItem(msg, "result");
cJSON *contents = cJSON_GetObjectItem(result, "contents");
@@ -170,6 +91,8 @@ void *lsp_thread(void *arg) {
pthread_mutex_unlock(&lsp_mutex);
if (matched->type == HOVER)
handle_hover_response(matched->buffer, msg);
else if (matched->type == INITIALIZED)
handle_initialized(msg);
free(matched);
break;
}
@@ -180,13 +103,56 @@ void *lsp_thread(void *arg) {
cJSON *method_json = cJSON_GetObjectItem(msg, "method");
if (method_json && cJSON_IsString(method_json)) {
const char *method = method_json->valuestring;
// send_notification(msg); TODO
if (method) {
if (strcmp(method, "textDocument/publishDiagnostics") == 0) {
cJSON *params = cJSON_GetObjectItem(msg, "params");
cJSON *diagnostics = cJSON_GetObjectItem(params, "diagnostics");
cJSON *diag = NULL;
const char *filename =
cJSON_GetObjectItem(params, "uri")->valuestring;
if (root.Root.focused && root.Root.focused->type == BUFFER) {
free(root.Root.focused->Buffer.errors);
root.Root.focused->Buffer.errors = NULL;
root.Root.focused->Buffer.error_count = 0;
cJSON_ArrayForEach(diag, diagnostics)
handle_diagnostic(diag, root.Root.focused);
}
}
}
}
}
cJSON_Delete(msg);
}
}
void handle_diagnostic(cJSON *diag, Node *buffer) {
cJSON *range = cJSON_GetObjectItem(diag, "range");
cJSON *start = cJSON_GetObjectItem(range, "start");
int start_line = cJSON_GetObjectItem(start, "line")->valueint;
int start_char = cJSON_GetObjectItem(start, "character")->valueint;
cJSON *end = cJSON_GetObjectItem(range, "end");
int end_line = cJSON_GetObjectItem(end, "line")->valueint;
int end_char = cJSON_GetObjectItem(end, "character")->valueint;
int severity = cJSON_GetObjectItem(diag, "severity")->valueint;
char *text = cJSON_GetObjectItem(diag, "message")->valuestring;
buffer->Buffer.errors =
realloc(buffer->Buffer.errors,
(buffer->Buffer.error_count + 1) * sizeof(LSPErrors));
buffer->Buffer.errors[buffer->Buffer.error_count].start_line = start_line;
buffer->Buffer.errors[buffer->Buffer.error_count].start_col = start_char;
buffer->Buffer.errors[buffer->Buffer.error_count].end_line = end_line;
buffer->Buffer.errors[buffer->Buffer.error_count].end_col = end_char;
buffer->Buffer.errors[buffer->Buffer.error_count].severity = severity;
buffer->Buffer.errors[buffer->Buffer.error_count].message = text;
buffer->Buffer.error_count++;
}
void handle_initialized(cJSON *_msg) {
cJSON *initialized = make_initialized_request();
lsp_send(initialized);
cJSON_Delete(initialized);
}
void send_notification(cJSON *msg) {
char *dump = cJSON_Print(msg);
wrap_text(dump, 200);
@@ -196,8 +162,8 @@ void send_notification(cJSON *msg) {
void lsp_setup(Node *buffer, uint8_t lang) {
if (lang == RUBY) {
char *argv[] = {"ruby-lsp", NULL};
start_lsp("ruby-lsp", argv);
char *argv[] = {"solargraph", "stdio", NULL};
start_lsp("solargraph", argv);
} else if (lang == C_LANG) {
char *argv[] = {"clangd", NULL};
start_lsp("clangd", argv);
@@ -206,6 +172,7 @@ void lsp_setup(Node *buffer, uint8_t lang) {
}
cJSON *init = make_folder_init_request(1, buffer->Buffer.folder);
lsp_send(init);
lsp_enqueue(INITIALIZED, 1, buffer);
cJSON_Delete(init);
char *text = lines_to_string(buffer->Buffer.data);
cJSON *req = make_open_file_request(buffer->Buffer.filename, "c", text, 1);
@@ -239,7 +206,7 @@ void handle_sigchld(int sig) {
pid_t pid;
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
if (pid == lsp_pid)
die("clangd exited");
die("lsp exited");
}
}
@@ -356,6 +323,15 @@ cJSON *make_folder_init_request(int id, const char *root_uri) {
return init;
}
cJSON *make_initialized_request() {
cJSON *msg = cJSON_CreateObject();
cJSON_AddStringToObject(msg, "jsonrpc", "2.0");
cJSON_AddStringToObject(msg, "method", "initialized");
cJSON *params = cJSON_CreateObject();
cJSON_AddItemToObject(msg, "params", params);
return msg;
}
cJSON *make_open_file_request(const char *uri, const char *languageId,
const char *text, int version) {
cJSON *msg = cJSON_CreateObject();