aboutsummaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
authorDavid Moc <personal@cdatgoose.org>2026-05-30 21:53:05 +0200
committerDavid Moc <personal@cdatgoose.org>2026-05-30 21:53:05 +0200
commite930cc6bdc7f62befac063d7d9d016ffb0a64f1a (patch)
tree52118a1e990ae88f5f0410c8caea129609e22e19 /src/main.c
Added the old repo, refactored it, added the C jit.
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c164
1 files changed, 164 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..9f388a0
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,164 @@
+#include "app.h"
+#include "config.h"
+#include "font.h"
+#include "render.h"
+
+#include <GLFW/glfw3.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#define WINDOW_WIDTH 1000
+#define WINDOW_HEIGHT 700
+
+static void print_usage(const char *argv0) {
+ fprintf(stderr, "usage:\n");
+ fprintf(stderr, " %s [--config path/to/ecexrc.c] [--font path/to/font.ttf]\n", argv0);
+ fprintf(stderr, "\n");
+ fprintf(stderr, "keys:\n");
+ fprintf(stderr, " F1 opens M-x\n");
+ fprintf(stderr, " Tab completes M-x command names\n");
+ fprintf(stderr, " Alt+x opens M-x when the OS/window-manager allows it\n");
+ fprintf(stderr, " C-x is reserved for prefix maps\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "env:\n");
+ fprintf(stderr, " ECEX_FONT=/path/to/font.ttf\n");
+ fprintf(stderr, " ECEX_INCLUDE=/path/to/ecex/include\n");
+}
+
+static int parse_args(int argc,
+ char **argv,
+ const char **config_path,
+ const char **font_path_arg) {
+ *config_path = NULL;
+ *font_path_arg = NULL;
+
+ for (int i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "--config") == 0) {
+ if (i + 1 >= argc) {
+ print_usage(argv[0]);
+ return -1;
+ }
+
+ *config_path = argv[++i];
+ } else if (strcmp(argv[i], "--font") == 0) {
+ if (i + 1 >= argc) {
+ print_usage(argv[0]);
+ return -1;
+ }
+
+ *font_path_arg = argv[++i];
+ } else if (strcmp(argv[i], "--help") == 0 ||
+ strcmp(argv[i], "-h") == 0) {
+ print_usage(argv[0]);
+ return 1;
+ } else {
+ *font_path_arg = argv[i];
+ }
+ }
+
+ return 0;
+}
+
+static const char *select_font_path(ecex_t *ed, const char *font_path_arg) {
+ if (font_path_arg) return font_path_arg;
+ if (ed && ed->theme.font_path) return ed->theme.font_path;
+ return font_choose_path(NULL);
+}
+
+int main(int argc, char **argv) {
+ const char *config_path = NULL;
+ const char *font_path_arg = NULL;
+
+ int args_result = parse_args(argc, argv, &config_path, &font_path_arg);
+ if (args_result != 0) {
+ return args_result < 0 ? 1 : 0;
+ }
+
+ ecex_t *ed = ecex_new();
+ if (!ed) {
+ fprintf(stderr, "failed to create editor\n");
+ return 1;
+ }
+
+ if (config_path) {
+ if (ecex_load_c_config(ed, config_path) != 0) {
+ fprintf(stderr, "ecex: continuing without config\n");
+ }
+ }
+
+ if (!glfwInit()) {
+ fprintf(stderr, "failed to initialize GLFW\n");
+ ecex_free(ed);
+ return 1;
+ }
+
+ GLFWwindow *window = glfwCreateWindow(
+ WINDOW_WIDTH,
+ WINDOW_HEIGHT,
+ "ecex",
+ NULL,
+ NULL
+ );
+
+ if (!window) {
+ fprintf(stderr, "failed to create GLFW window\n");
+ glfwTerminate();
+ ecex_free(ed);
+ return 1;
+ }
+
+ glfwMakeContextCurrent(window);
+ glfwSwapInterval(1);
+
+ app_t app;
+ app_init(&app, ed);
+ app_set_window(&app, window);
+
+ const char *font_path = select_font_path(ed, font_path_arg);
+ if (!font_path) {
+ fprintf(stderr, "ecex: could not find a font automatically\n");
+ fprintf(stderr, "try:\n");
+ fprintf(stderr, " export ECEX_FONT=/path/to/font.ttf\n");
+ fprintf(stderr, " %s --font /path/to/font.ttf\n", argv[0]);
+
+ glfwDestroyWindow(window);
+ glfwTerminate();
+ ecex_free(ed);
+ return 1;
+ }
+
+ if (font_load(&app.font, font_path, ed->theme.font_size) != 0) {
+ fprintf(stderr, "ecex: could not load font\n");
+ fprintf(stderr, "try an explicit font path:\n");
+ fprintf(stderr, " %s --font /path/to/font.ttf\n", argv[0]);
+
+ glfwDestroyWindow(window);
+ glfwTerminate();
+ ecex_free(ed);
+ return 1;
+ }
+
+ snprintf(app.font_path, sizeof(app.font_path), "%s", font_path);
+
+ app_install_callbacks(&app);
+ app_message(&app, "F1 for M-x. Tab completes commands.");
+
+ while (!glfwWindowShouldClose(window) && !ed->should_quit) {
+ if (app.dirty) {
+ render(&app);
+ glfwSwapBuffers(window);
+ app.dirty = 0;
+ }
+
+ glfwWaitEvents();
+ }
+
+ font_free(&app.font);
+
+ glfwDestroyWindow(window);
+ glfwTerminate();
+
+ ecex_free(ed);
+ return 0;
+}