summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dged/syntax.c93
-rw-r--r--src/main/main.c42
2 files changed, 81 insertions, 54 deletions
diff --git a/src/dged/syntax.c b/src/dged/syntax.c
index 7f13b11..61f09c2 100644
--- a/src/dged/syntax.c
+++ b/src/dged/syntax.c
@@ -21,8 +21,8 @@
#include "text.h"
#include "vec.h"
-static char *treesitter_path = NULL;
-static bool treesitter_path_allocated = false;
+static char *treesitter_path[256] = {0};
+static uint32_t treesitter_path_len = 0;
static const char *parser_filename = "parser";
static const char *highlight_path = "queries/highlights.scm";
@@ -120,15 +120,14 @@ static const char *grammar_name_from_buffer(struct buffer *buffer) {
return buffer->lang.name;
}
-static const char *lang_folder(struct buffer *buffer) {
+static const char *lang_folder(struct buffer *buffer, const char *path) {
const char *langname = grammar_name_from_buffer(buffer);
-
- size_t tspath_len = strlen(treesitter_path);
+ size_t tspath_len = strlen(path);
size_t lang_len = strlen(langname);
char *fld = malloc(tspath_len + lang_len + 2);
uint32_t idx = 0;
- memcpy(&fld[idx], treesitter_path, tspath_len);
+ memcpy(&fld[idx], path, tspath_len);
idx += tspath_len;
fld[idx++] = '/';
for (uint32_t i = 0; i < lang_len; ++i) {
@@ -489,33 +488,44 @@ static void text_inserted(struct buffer *buffer, struct region inserted,
}
static void create_parser(struct buffer *buffer, void *userdata) {
- const char *lang_root = lang_folder(buffer);
- const char *filename = join_path(lang_root, parser_filename);
- void *h = dlopen(filename, RTLD_LAZY);
- free((void *)filename);
- if (h == NULL) {
- free((void *)lang_root);
- return;
- }
+ TSLanguage *(*langsym)() = NULL;
+ const char *lang_root = NULL, *langname = NULL;
+ void *h = NULL;
- const char *langname = grammar_name_from_buffer(buffer);
- size_t lang_len = strlen(langname);
+ for (uint32_t i = 0; i < treesitter_path_len && langsym == NULL; ++i) {
+ const char *path = treesitter_path[i];
+ lang_root = lang_folder(buffer, path);
+ const char *filename = join_path(lang_root, parser_filename);
- const char *prefix = "tree_sitter_";
- size_t prefix_len = strlen(prefix);
- char *function = malloc(prefix_len + lang_len + 1);
- memcpy(function, prefix, prefix_len);
- for (uint32_t i = 0; i < lang_len; ++i) {
- function[prefix_len + i] = tolower(langname[i]);
+ h = dlopen(filename, RTLD_LAZY);
+ free((void *)filename);
+ if (h == NULL) {
+ free((void *)lang_root);
+ continue;
+ }
+
+ langname = grammar_name_from_buffer(buffer);
+ size_t lang_len = strlen(langname);
+
+ const char *prefix = "tree_sitter_";
+ size_t prefix_len = strlen(prefix);
+ char *function = malloc(prefix_len + lang_len + 1);
+ memcpy(function, prefix, prefix_len);
+ for (uint32_t i = 0; i < lang_len; ++i) {
+ function[prefix_len + i] = tolower(langname[i]);
+ }
+ function[prefix_len + lang_len] = '\0';
+ langsym = dlsym(h, function);
+
+ free(function);
+ if (langsym == NULL) {
+ free((void *)lang_root);
+ dlclose(h);
+ }
}
- function[prefix_len + lang_len] = '\0';
- TSLanguage *(*langsym)() = dlsym(h, function);
- free(function);
if (langsym == NULL) {
- free((void *)lang_root);
- dlclose(h);
return;
}
@@ -550,28 +560,11 @@ static void create_parser(struct buffer *buffer, void *userdata) {
buffer_add_destroy_hook(buffer, delete_parser, hl);
}
-#define xstr(s) str(s)
-#define str(s) #s
-
-void syntax_init() {
- treesitter_path = getenv("TREESITTER_GRAMMARS");
- if (treesitter_path == NULL) {
- treesitter_path = (char *)join_path(xstr(DATADIR), "grammars");
- treesitter_path_allocated = true;
- }
+void syntax_init(uint32_t grammar_path_len, const char *grammar_path[]) {
- struct stat buffer;
- if (stat(treesitter_path, &buffer) != 0) {
- minibuffer_echo_timeout(4,
- "failed to initialize syntax, TREESITTER_GRAMMARS "
- "not set and grammars dir does not exist at %s.",
- treesitter_path);
-
- if (treesitter_path_allocated) {
- free(treesitter_path);
- }
-
- return;
+ treesitter_path_len = grammar_path_len < 256 ? grammar_path_len : 256;
+ for (uint32_t i = 0; i < treesitter_path_len; ++i) {
+ treesitter_path[i] = strdup(grammar_path[i]);
}
// TODO: check that it exists
@@ -585,7 +578,7 @@ void syntax_init() {
}
void syntax_teardown() {
- if (treesitter_path_allocated) {
- free(treesitter_path);
+ for (uint32_t i = 0; i < treesitter_path_len; ++i) {
+ free((void *)treesitter_path[i]);
}
}
diff --git a/src/main/main.c b/src/main/main.c
index 348ac1e..e722ed2 100644
--- a/src/main/main.c
+++ b/src/main/main.c
@@ -22,6 +22,9 @@
#ifdef SYNTAX_ENABLE
#include "dged/syntax.h"
+
+#define xstr(s) str(s)
+#define str(s) #s
#endif
#include "bindings.h"
@@ -67,6 +70,7 @@ uint64_t calc_frame_time_ns(struct timespec *timers, uint32_t num_timer_pairs) {
#define TIMED_SCOPE_BEGIN(timer) clock_gettime(CLOCK_MONOTONIC, &timer##_begin)
#define TIMED_SCOPE_END(timer) clock_gettime(CLOCK_MONOTONIC, &timer##_end)
+#define INVALID_WATCH -1
struct watched_file {
uint32_t watch_id;
struct buffer *buffer;
@@ -95,7 +99,8 @@ void reload_buffer(struct buffer *buffer) {
void update_file_watches(struct reactor *reactor) {
// first, find invalid file watches and try to update them
VEC_FOR_EACH(&g_watched_files, struct watched_file * w) {
- if (w->watch_id == -1) {
+ if (w->watch_id == INVALID_WATCH) {
+ message("re-watching: %s", w->buffer->filename);
w->watch_id =
reactor_watch_file(reactor, w->buffer->filename, FileWritten);
reload_buffer(w->buffer);
@@ -109,7 +114,8 @@ void update_file_watches(struct reactor *reactor) {
VEC_FOR_EACH(&g_watched_files, struct watched_file * w) {
if (w->watch_id == ev.id) {
if ((ev.mask & LastEvent) != 0) {
- w->watch_id = -1;
+ message("lost watched file: %s", w->buffer->filename);
+ w->watch_id = INVALID_WATCH;
continue;
}
@@ -222,8 +228,35 @@ int main(int argc, char *argv[]) {
minibuffer_init(&minibuffer, &buflist);
buffers_add_add_hook(&buflist, watch_file, (void *)reactor);
+
#ifdef SYNTAX_ENABLE
- syntax_init();
+ char *treesitter_path_env = getenv("TREESITTER_GRAMMARS");
+ const char *builtin_path = join_path(xstr(DATADIR), "grammars");
+
+ const char *treesitter_path[256] = {0};
+ uint32_t treesitter_path_len = 0;
+
+ if (treesitter_path_env != NULL) {
+ treesitter_path_env = strdup(treesitter_path_env);
+ char *result = strtok(treesitter_path_env, ":");
+ while (result != NULL && treesitter_path_len < 256) {
+ treesitter_path[treesitter_path_len] = result;
+ ++treesitter_path_len;
+ result = strtok(NULL, ":");
+ }
+ }
+
+ if (treesitter_path_len < 256) {
+ treesitter_path[treesitter_path_len] = builtin_path;
+ ++treesitter_path_len;
+ }
+
+ syntax_init(treesitter_path_len, treesitter_path);
+
+ if (treesitter_path_env != NULL) {
+ free((void *)treesitter_path_env);
+ }
+ free((void *)builtin_path);
#endif
struct buffer initial_buffer = buffer_create("welcome");
@@ -234,7 +267,8 @@ int main(int argc, char *argv[]) {
free((void *)filename);
free((void *)absfile);
} else {
- const char *welcome_txt = "Welcome to the editor for datagubbar 👴\n";
+ const char *welcome_txt =
+ "Welcome to the editor for datagubbar and datagummor 👴👵\n";
buffer_set_text(&initial_buffer, (uint8_t *)welcome_txt,
strlen(welcome_txt));
}