Random Stuff
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user