From a15cb041654ae307add0b998b526c87c3f42bf5f Mon Sep 17 00:00:00 2001 From: David Moc Date: Tue, 2 Jun 2026 13:50:21 +0200 Subject: Add plugin hooks and mode plugins --- config/markdown_plugin.c | 68 ++++++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 25 deletions(-) (limited to 'config/markdown_plugin.c') diff --git a/config/markdown_plugin.c b/config/markdown_plugin.c index ded0e1c..1026d31 100644 --- a/config/markdown_plugin.c +++ b/config/markdown_plugin.c @@ -3,9 +3,28 @@ #define MD_TEXT_TITLE 1 typedef struct md_state { - ecex_t *ed; + ecex_plugin_t *plugin; } md_state_t; +static int md_line_is_fence(const char *line) { + const char *p = line; + if (!p) return 0; + while (*p == ' ' || *p == '\t') ++p; + return p[0] == '`' && p[1] == '`' && p[2] == '`'; +} + +static int md_in_code_at_line(buffer_t *buffer, int line) { + char scratch[256]; + int in_code = 0; + int i; + if (!buffer || line <= 0) return 0; + for (i = 0; i < line; ++i) { + if (ecex_buffer_line_copy_text(buffer, i, scratch, (int)sizeof(scratch)) < 0) continue; + if (md_line_is_fence(scratch)) in_code = !in_code; + } + return in_code; +} + static int md_render(ecex_t *ed, buffer_t *buffer, ecex_draw_context_t *ctx, void *userdata) { md_state_t *state = (md_state_t *)userdata; int draw_count; @@ -19,31 +38,32 @@ static int md_render(ecex_t *ed, buffer_t *buffer, ecex_draw_context_t *ctx, voi if (!ed || !buffer || !ctx || !state) return 0; - draw_count = ecex_var_i32(ed, state, "draw_count", 0) + 1; - ecex_var_i32_set_scalar(ed, state, "draw_count", draw_count); + draw_count = ecex_plugin_slot_i32_get_scalar(state->plugin, "draw_count", 0) + 1; + ecex_plugin_slot_i32_set_scalar(state->plugin, "draw_count", draw_count); if (draw_count <= 2 || (draw_count % 120) == 0) { ecex_log_int("markdown_plugin_draw: count=", draw_count); } - line_count = ecex_buffer_line_count_i(buffer); + line_count = ecex_buffer_line_count_int(buffer); ecex_log_int("markdown_plugin_draw: line_count=", line_count); if (line_count < 0) line_count = 0; - ecex_text_set_buffer_title(ed, state, MD_TEXT_TITLE, buffer); - ecex_draw_markdown_canvas_auto_i(ctx, state, MD_TEXT_TITLE); + ecex_plugin_text_set_from_buffer_title(state->plugin, MD_TEXT_TITLE, buffer); + ecex_draw_markdown_canvas_auto_i(ctx, state->plugin, MD_TEXT_TITLE); - y = ecex_markdown_body_y_i(ctx); - h = ecex_draw_context_height_i(ctx); - line_h = ecex_draw_context_line_height_i(ctx); - scroll = ecex_buffer_scroll_line(buffer); + y = ecex_markdown_body_y_px(ctx); + h = ecex_draw_context_height_px(ctx); + line_h = ecex_draw_context_line_height_px(ctx); + scroll = ecex_buffer_scroll_line_index(buffer); if (scroll < 0) scroll = 0; if (scroll > line_count) scroll = line_count; + in_code = md_in_code_at_line(buffer, scroll); for (i = scroll; i < line_count && y < h - line_h; ++i) { int packed; int advance; if (i < scroll + 4) ecex_log_int("markdown_plugin_draw: host line=", i); - packed = ecex_markdown_draw_line_from_buffer_i(ctx, state, buffer, i, y, in_code); + packed = ecex_markdown_draw_buffer_line_i(ctx, state->plugin, buffer, i, y, in_code); in_code = (packed & 0x10000) ? 1 : 0; advance = packed & 0xffff; if (advance <= 0) advance = line_h; @@ -55,12 +75,9 @@ static int md_render(ecex_t *ed, buffer_t *buffer, ecex_draw_context_t *ctx, voi static void md_free_state(void *userdata) { md_state_t *state = (md_state_t *)userdata; - ecex_t *ed; if (!state) return; - ed = state->ed; - ecex_text_free_owner(ed, state); - ecex_var_free_owner(ed, state); - ecex_object_free(ed, state); + ecex_plugin_text_free_all(state->plugin); + ecex_plugin_object_free(state->plugin, state); } static int md_view_buffer(ecex_t *ed, buffer_t *buffer) { @@ -68,12 +85,13 @@ static int md_view_buffer(ecex_t *ed, buffer_t *buffer) { if (!ed || !buffer) return -1; if (ecex_buffer_has_renderer(buffer)) ecex_buffer_clear_renderer(buffer); - state = (md_state_t *)ecex_object_calloc(ed, 1, sizeof(*state)); + ecex_plugin_t *plugin = ecex_plugin_find(ed, "markdown"); + state = (md_state_t *)ecex_plugin_object_calloc(plugin, "state", 1, sizeof(*state)); if (!state) return -1; - state->ed = ed; + state->plugin = plugin; if (ecex_buffer_set_renderer(buffer, md_render, state, md_free_state, ECEX_RENDER_REPLACE_CONTENT) != 0) { - ecex_object_free(ed, state); + ecex_plugin_object_free(plugin, state); return -1; } ecex_buffer_set_major_mode_by_name(ed, buffer, "markdown-mode"); @@ -105,19 +123,19 @@ static int cmd_markdown_toggle(ecex_t *ed) { return md_view_buffer(ed, buffer); } -int ecex_markdown_plugin(ecex_t *ed) { +ECEX_PLUGIN_BEGIN(ecex_markdown_plugin, "markdown") ECEX_CONFIG_MODE("markdown-mode"); ECEX_CONFIG_COMMAND("markdown-view", cmd_markdown_view); ECEX_CONFIG_COMMAND("markdown-source", cmd_markdown_source); ECEX_CONFIG_COMMAND("markdown-toggle", cmd_markdown_toggle); ECEX_CONFIG_MODE_BIND("markdown-mode", "C-c C-c", "markdown-toggle"); ECEX_CONFIG_MODE_BIND("markdown-mode", "C-c C-s", "markdown-source"); - ecex_register_file_handler(ed, ".md", md_file_handler); - ecex_register_file_handler(ed, ".markdown", md_file_handler); - ecex_register_file_handler(ed, ".mdown", md_file_handler); - ecex_register_file_handler(ed, ".mkd", md_file_handler); + ECEX_CONFIG_TRY(ecex_plugin_file_handler_register(plugin, ".md", md_file_handler)); + ECEX_CONFIG_TRY(ecex_plugin_file_handler_register(plugin, ".markdown", md_file_handler)); + ECEX_CONFIG_TRY(ecex_plugin_file_handler_register(plugin, ".mdown", md_file_handler)); + ECEX_CONFIG_TRY(ecex_plugin_file_handler_register(plugin, ".mkd", md_file_handler)); return 0; -} +ECEX_PLUGIN_END #ifndef ECEX_NO_STANDALONE_CONFIG ECEX_CONFIG_BEGIN -- cgit v1.2.3