Random Stuff
This commit is contained in:
20
README.md
Normal file
20
README.md
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Cubit
|
||||||
|
|
||||||
|
> It is still under developmant.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
It is a vimmish editor with hopefully everything an IDE can have for ruby/c/c++ & html/css/js workflows.
|
||||||
|
|
||||||
|
## TODO
|
||||||
|
|
||||||
|
- Fix lsp handling to support varying standards.
|
||||||
|
- Add support for other languages.
|
||||||
|
- Make it a bit more stable.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- It currently supports tree-sitter syntax highlighting for ruby and c/c++.
|
||||||
|
- It also supports their respective LSP's.
|
||||||
|
- Solargraph for ruby.
|
||||||
|
- clangd for c/c++.
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "editor.h"
|
#include "editor.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "snake.h"
|
#include "snake.h"
|
||||||
|
#include <ctype.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -20,14 +21,80 @@ void die(const char *s) {
|
|||||||
usleep(1000000000);
|
usleep(1000000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int is_word_char(char c) { return isalnum((unsigned char)c) || c == '_'; }
|
||||||
|
|
||||||
|
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 (!is_word_char(*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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
size_t clamp_to_visible(BufferData *e, int row, int dir) {
|
size_t clamp_to_visible(BufferData *e, int row, int dir) {
|
||||||
if (row < 0)
|
if (row < 0)
|
||||||
return 0;
|
return 0;
|
||||||
if ((size_t)row >= e->line_count)
|
if ((size_t)row >= e->line_count)
|
||||||
return e->line_count - 1;
|
return e->line_count - 1;
|
||||||
while (row >= 0 && (size_t)row < e->line_count && line_is_hidden(e, row)) {
|
while (row >= 0 && (size_t)row < e->line_count && line_is_hidden(e, row))
|
||||||
row += dir;
|
row += dir;
|
||||||
}
|
|
||||||
if (row < 0)
|
if (row < 0)
|
||||||
return 0;
|
return 0;
|
||||||
if ((size_t)row >= e->line_count)
|
if ((size_t)row >= e->line_count)
|
||||||
|
|||||||
@@ -22,3 +22,6 @@ char *line_to_string(Line *line);
|
|||||||
char *lines_to_string(BufferData *e);
|
char *lines_to_string(BufferData *e);
|
||||||
uint32_t fnv1a_32(const char *data, size_t len);
|
uint32_t fnv1a_32(const char *data, size_t len);
|
||||||
int file_type(const char *filename);
|
int file_type(const char *filename);
|
||||||
|
void measure_text(const char *text, int *out_lines, int *out_longest);
|
||||||
|
int is_word_char(char c);
|
||||||
|
void wrap_text(char *text, int max_width);
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
#include "ruby_ts_table.h"
|
#include "ruby_ts_table.h"
|
||||||
#include "snake.h"
|
#include "snake.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@@ -145,10 +144,6 @@ void append_highlight_byte(Line *line, size_t start_col, size_t end_col,
|
|||||||
h->end_col = end;
|
h->end_col = end;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int is_word_char(char c) {
|
|
||||||
return isalnum((unsigned char)c) || c == '_';
|
|
||||||
}
|
|
||||||
|
|
||||||
void append_highlight(Line *lh, size_t start_col, size_t end_col, Color *fg,
|
void append_highlight(Line *lh, size_t start_col, size_t end_col, Color *fg,
|
||||||
Color *bg, uint8_t flags) {
|
Color *bg, uint8_t flags) {
|
||||||
lh->highlight_count++;
|
lh->highlight_count++;
|
||||||
@@ -253,6 +248,56 @@ void word_highlighter(Node *buffer) {
|
|||||||
append_highlight(virt, y, y + 1, (Color *)colors + DARK, NULL, 0b010);
|
append_highlight(virt, y, y + 1, (Color *)colors + DARK, NULL, 0b010);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// now handle lsp errors hl
|
||||||
|
for (size_t i = 0; i < e->line_count; i++) {
|
||||||
|
Line *l = e->lines[i];
|
||||||
|
if (!l)
|
||||||
|
continue;
|
||||||
|
for (int j = 0; j < buffer->Buffer.error_count; j++) {
|
||||||
|
int start_line = buffer->Buffer.errors[j].start_line;
|
||||||
|
int end_line = buffer->Buffer.errors[j].end_line;
|
||||||
|
int start_col = buffer->Buffer.errors[j].start_col;
|
||||||
|
int end_col = buffer->Buffer.errors[j].end_col;
|
||||||
|
if (start_line <= i && end_line >= i) {
|
||||||
|
if (i == start_line && i == end_line)
|
||||||
|
append_highlight(l, start_col, end_col, NULL, NULL, 0b000);
|
||||||
|
else if (i == start_line)
|
||||||
|
append_highlight(l, start_col, l->cluster_count, NULL, NULL, 0b000);
|
||||||
|
else if (i == end_line)
|
||||||
|
append_highlight(l, 0, end_col, NULL, (Color *)colors + RED, 0b000);
|
||||||
|
else
|
||||||
|
append_highlight(l, 0, l->cluster_count, NULL, NULL, 0b000);
|
||||||
|
if (i == start_line) {
|
||||||
|
VirtLine *virt = e->virtual_lines[i];
|
||||||
|
if (!virt) {
|
||||||
|
virt = calloc(1, sizeof(VirtLine));
|
||||||
|
if (!virt)
|
||||||
|
die("calloc failed");
|
||||||
|
virt->line_count = 1;
|
||||||
|
virt->lines = calloc(1, sizeof(Line *));
|
||||||
|
if (!virt->lines)
|
||||||
|
die("calloc failed");
|
||||||
|
virt->lines[0] = calloc(1, sizeof(Line));
|
||||||
|
e->virtual_lines[i] = virt;
|
||||||
|
}
|
||||||
|
if (!virt->lines) {
|
||||||
|
virt->line_count = 1;
|
||||||
|
virt->lines = calloc(1, sizeof(Line *));
|
||||||
|
if (!virt->lines)
|
||||||
|
die("calloc failed");
|
||||||
|
virt->lines[0] = calloc(1, sizeof(Line));
|
||||||
|
}
|
||||||
|
Line *virt_l = virt->lines[0];
|
||||||
|
virt_l->cluster_count = l->cluster_count + 5;
|
||||||
|
virt_l->clusters = calloc(l->cluster_count + 5, sizeof(Cluster));
|
||||||
|
for (size_t y = l->cluster_count; y < l->cluster_count + 5; y++) {
|
||||||
|
virt_l->clusters[y].utf8 = strdup("·");
|
||||||
|
virt_l->clusters[y].width = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!e || e->line_count == 0)
|
if (!e || e->line_count == 0)
|
||||||
return;
|
return;
|
||||||
Line *line = e->lines[e->cursor_row];
|
Line *line = e->lines[e->cursor_row];
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "helper_functions.h"
|
#include "helper_functions.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include <ctype.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -19,17 +18,6 @@ int lsp_pid = -1;
|
|||||||
int version = 1;
|
int version = 1;
|
||||||
int c_id = 1;
|
int c_id = 1;
|
||||||
pthread_mutex_t lsp_mutex = PTHREAD_MUTEX_INITIALIZER;
|
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;
|
LspQueue *lsp_head = NULL;
|
||||||
|
|
||||||
void lsp_enqueue(LspRequestType type, int id, Node *buffer) {
|
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);
|
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) {
|
void handle_hover_response(Node *buffer, cJSON *msg) {
|
||||||
cJSON *result = cJSON_GetObjectItem(msg, "result");
|
cJSON *result = cJSON_GetObjectItem(msg, "result");
|
||||||
cJSON *contents = cJSON_GetObjectItem(result, "contents");
|
cJSON *contents = cJSON_GetObjectItem(result, "contents");
|
||||||
@@ -170,6 +91,8 @@ void *lsp_thread(void *arg) {
|
|||||||
pthread_mutex_unlock(&lsp_mutex);
|
pthread_mutex_unlock(&lsp_mutex);
|
||||||
if (matched->type == HOVER)
|
if (matched->type == HOVER)
|
||||||
handle_hover_response(matched->buffer, msg);
|
handle_hover_response(matched->buffer, msg);
|
||||||
|
else if (matched->type == INITIALIZED)
|
||||||
|
handle_initialized(msg);
|
||||||
free(matched);
|
free(matched);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -180,13 +103,56 @@ void *lsp_thread(void *arg) {
|
|||||||
cJSON *method_json = cJSON_GetObjectItem(msg, "method");
|
cJSON *method_json = cJSON_GetObjectItem(msg, "method");
|
||||||
if (method_json && cJSON_IsString(method_json)) {
|
if (method_json && cJSON_IsString(method_json)) {
|
||||||
const char *method = method_json->valuestring;
|
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);
|
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) {
|
void send_notification(cJSON *msg) {
|
||||||
char *dump = cJSON_Print(msg);
|
char *dump = cJSON_Print(msg);
|
||||||
wrap_text(dump, 200);
|
wrap_text(dump, 200);
|
||||||
@@ -196,8 +162,8 @@ void send_notification(cJSON *msg) {
|
|||||||
|
|
||||||
void lsp_setup(Node *buffer, uint8_t lang) {
|
void lsp_setup(Node *buffer, uint8_t lang) {
|
||||||
if (lang == RUBY) {
|
if (lang == RUBY) {
|
||||||
char *argv[] = {"ruby-lsp", NULL};
|
char *argv[] = {"solargraph", "stdio", NULL};
|
||||||
start_lsp("ruby-lsp", argv);
|
start_lsp("solargraph", argv);
|
||||||
} else if (lang == C_LANG) {
|
} else if (lang == C_LANG) {
|
||||||
char *argv[] = {"clangd", NULL};
|
char *argv[] = {"clangd", NULL};
|
||||||
start_lsp("clangd", argv);
|
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);
|
cJSON *init = make_folder_init_request(1, buffer->Buffer.folder);
|
||||||
lsp_send(init);
|
lsp_send(init);
|
||||||
|
lsp_enqueue(INITIALIZED, 1, buffer);
|
||||||
cJSON_Delete(init);
|
cJSON_Delete(init);
|
||||||
char *text = lines_to_string(buffer->Buffer.data);
|
char *text = lines_to_string(buffer->Buffer.data);
|
||||||
cJSON *req = make_open_file_request(buffer->Buffer.filename, "c", text, 1);
|
cJSON *req = make_open_file_request(buffer->Buffer.filename, "c", text, 1);
|
||||||
@@ -239,7 +206,7 @@ void handle_sigchld(int sig) {
|
|||||||
pid_t pid;
|
pid_t pid;
|
||||||
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
|
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
|
||||||
if (pid == lsp_pid)
|
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;
|
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,
|
cJSON *make_open_file_request(const char *uri, const char *languageId,
|
||||||
const char *text, int version) {
|
const char *text, int version) {
|
||||||
cJSON *msg = cJSON_CreateObject();
|
cJSON *msg = cJSON_CreateObject();
|
||||||
|
|||||||
@@ -8,6 +8,18 @@
|
|||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
INITIALIZED,
|
||||||
|
HOVER,
|
||||||
|
} LspRequestType;
|
||||||
|
typedef struct LspQueue LspQueue;
|
||||||
|
typedef struct LspQueue {
|
||||||
|
LspRequestType type;
|
||||||
|
int id;
|
||||||
|
Node *buffer;
|
||||||
|
struct LspQueue *next;
|
||||||
|
} LspQueue;
|
||||||
|
|
||||||
void start_lsp(const char *cmd, char *const argv[]);
|
void start_lsp(const char *cmd, char *const argv[]);
|
||||||
void lsp_send(cJSON *msg);
|
void lsp_send(cJSON *msg);
|
||||||
cJSON *lsp_recv();
|
cJSON *lsp_recv();
|
||||||
@@ -24,3 +36,7 @@ void lsp_setup(Node *buffer, uint8_t lang);
|
|||||||
void lsp_change(Node *buffer, size_t start_line, size_t start_col,
|
void lsp_change(Node *buffer, size_t start_line, size_t start_col,
|
||||||
size_t end_line, size_t end_col, const char *new_text);
|
size_t end_line, size_t end_col, const char *new_text);
|
||||||
void lsp_hover(Node *buffer, size_t line, size_t character);
|
void lsp_hover(Node *buffer, size_t line, size_t character);
|
||||||
|
void send_notification(cJSON *msg);
|
||||||
|
cJSON *make_initialized_request();
|
||||||
|
void handle_initialized(cJSON *_msg);
|
||||||
|
void handle_diagnostic(cJSON *diag, Node *buffer);
|
||||||
|
|||||||
11
src/node.h
11
src/node.h
@@ -53,6 +53,15 @@ typedef struct ColHighlight {
|
|||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
} ColHighlight;
|
} ColHighlight;
|
||||||
|
|
||||||
|
typedef struct LSPErrors {
|
||||||
|
size_t start_line;
|
||||||
|
size_t start_col;
|
||||||
|
size_t end_line;
|
||||||
|
size_t end_col;
|
||||||
|
char *message;
|
||||||
|
uint8_t severity;
|
||||||
|
} LSPErrors;
|
||||||
|
|
||||||
typedef void (*HlFunc)(Node *e);
|
typedef void (*HlFunc)(Node *e);
|
||||||
typedef void (*LspUpdateFunc)(Node *e);
|
typedef void (*LspUpdateFunc)(Node *e);
|
||||||
typedef void (*LspChangeFunc)(Node *e, size_t start_line, size_t start_col,
|
typedef void (*LspChangeFunc)(Node *e, size_t start_line, size_t start_col,
|
||||||
@@ -106,6 +115,8 @@ struct Node {
|
|||||||
BufferData *data;
|
BufferData *data;
|
||||||
HlFunc hl_func_basic;
|
HlFunc hl_func_basic;
|
||||||
HlFunc hl_func_syntax;
|
HlFunc hl_func_syntax;
|
||||||
|
LSPErrors *errors;
|
||||||
|
uint8_t error_count;
|
||||||
char *filename;
|
char *filename;
|
||||||
char *folder;
|
char *folder;
|
||||||
_Bool hidden;
|
_Bool hidden;
|
||||||
|
|||||||
@@ -159,7 +159,6 @@ cJSON *make_folder_init_request(int id, const char *root_uri) {
|
|||||||
cJSON *params = cJSON_CreateObject();
|
cJSON *params = cJSON_CreateObject();
|
||||||
cJSON_AddStringToObject(params, "rootUri", root_uri);
|
cJSON_AddStringToObject(params, "rootUri", root_uri);
|
||||||
|
|
||||||
// capabilities
|
|
||||||
cJSON *capabilities = cJSON_CreateObject();
|
cJSON *capabilities = cJSON_CreateObject();
|
||||||
cJSON *textDocument = cJSON_CreateObject();
|
cJSON *textDocument = cJSON_CreateObject();
|
||||||
cJSON *diagnosticProvider = cJSON_CreateObject();
|
cJSON *diagnosticProvider = cJSON_CreateObject();
|
||||||
@@ -297,8 +296,8 @@ void print_wrapped(const char *text) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
char *argv[] = {"clangd", NULL};
|
char *argv[] = {"ruby-lsp", NULL};
|
||||||
start_lsp("clangd", argv);
|
start_lsp("ruby-lsp", argv);
|
||||||
cJSON *init =
|
cJSON *init =
|
||||||
make_folder_init_request(1, "file:///home/syed/main/cubit/tests/");
|
make_folder_init_request(1, "file:///home/syed/main/cubit/tests/");
|
||||||
lsp_send(init);
|
lsp_send(init);
|
||||||
@@ -306,10 +305,10 @@ int main() {
|
|||||||
cJSON *initialized = make_initialized_request();
|
cJSON *initialized = make_initialized_request();
|
||||||
lsp_send(initialized);
|
lsp_send(initialized);
|
||||||
cJSON_Delete(initialized);
|
cJSON_Delete(initialized);
|
||||||
char *text = read_file("/home/syed/main/cubit/tests/test.c");
|
char *text = read_file("/home/syed/main/cubit/tests/test.rb");
|
||||||
printf("%s\n", text);
|
printf("%s\n", text);
|
||||||
cJSON *req = make_open_file_request(
|
cJSON *req = make_open_file_request(
|
||||||
"file:///home/syed/main/cubit/tests/test.c", "c", text, 1);
|
"file:///home/syed/main/cubit/tests/test.rb", "ruby", text, 1);
|
||||||
lsp_send(req);
|
lsp_send(req);
|
||||||
cJSON_Delete(req);
|
cJSON_Delete(req);
|
||||||
free(text);
|
free(text);
|
||||||
@@ -328,7 +327,7 @@ int main() {
|
|||||||
break;
|
break;
|
||||||
if (key == 'f') {
|
if (key == 'f') {
|
||||||
cJSON *req = make_fold_request(
|
cJSON *req = make_fold_request(
|
||||||
next_id++, "file:///home/syed/main/cubit/tests/test.c");
|
next_id++, "file:///home/syed/main/cubit/tests/test.rb");
|
||||||
lsp_send(req);
|
lsp_send(req);
|
||||||
cJSON_Delete(req);
|
cJSON_Delete(req);
|
||||||
}
|
}
|
||||||
@@ -340,13 +339,13 @@ int main() {
|
|||||||
}
|
}
|
||||||
if (key == 'h') {
|
if (key == 'h') {
|
||||||
cJSON *req = make_hover_request(
|
cJSON *req = make_hover_request(
|
||||||
next_id++, "file:///home/syed/main/cubit/tests/test.c");
|
next_id++, "file:///home/syed/main/cubit/tests/test.rb");
|
||||||
lsp_send(req);
|
lsp_send(req);
|
||||||
cJSON_Delete(req);
|
cJSON_Delete(req);
|
||||||
}
|
}
|
||||||
if (key == 'c') {
|
if (key == 'c') {
|
||||||
cJSON *req = make_change_file_request(
|
cJSON *req = make_change_file_request(
|
||||||
next_id++, "file:///home/syed/main/cubit/tests/test.c");
|
next_id++, "file:///home/syed/main/cubit/tests/test.rb");
|
||||||
lsp_send(req);
|
lsp_send(req);
|
||||||
cJSON_Delete(req);
|
cJSON_Delete(req);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ bool_f = false
|
|||||||
nil_val = nil
|
nil_val = nil
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# --- Strings and symbols
|
# --- Strings and symbols
|
||||||
s1 = "double-quoted string with escape\nand interpolation: #{int_lit}"
|
s1 = "double-quoted string with escape\nand interpolation: #{int_lit}"
|
||||||
s2 = 'single-quoted string with \\n literal'
|
s2 = 'single-quoted string with \\n literal'
|
||||||
@@ -382,15 +383,6 @@ hex = 0xff
|
|||||||
oct = 0o755
|
oct = 0o755
|
||||||
bin = 0b101010
|
bin = 0b101010
|
||||||
|
|
||||||
# --- Case with guards
|
|
||||||
val = 10
|
|
||||||
case val
|
|
||||||
when Integer if val.even?
|
|
||||||
case_guard = :even_int
|
|
||||||
else
|
|
||||||
case_guard = :other
|
|
||||||
end
|
|
||||||
|
|
||||||
# --- Ternary, safe nav, assignment forms
|
# --- Ternary, safe nav, assignment forms
|
||||||
tern = val > 5 ? :big : :small
|
tern = val > 5 ? :big : :small
|
||||||
safe_len = nil&.to_s&.length
|
safe_len = nil&.to_s&.length
|
||||||
|
|||||||
Reference in New Issue
Block a user