From 6aeaa171dc1ca43392f53cbd02097f76e1b1c5a0 Mon Sep 17 00:00:00 2001 From: David Moc Date: Sun, 31 May 2026 03:47:04 +0200 Subject: Hardened API, tetris, MD-View --- config/markdown_plugin.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 config/markdown_plugin.c (limited to 'config/markdown_plugin.c') diff --git a/config/markdown_plugin.c b/config/markdown_plugin.c new file mode 100644 index 0000000..ded0e1c --- /dev/null +++ b/config/markdown_plugin.c @@ -0,0 +1,126 @@ +#include "ecex.h" + +#define MD_TEXT_TITLE 1 + +typedef struct md_state { + ecex_t *ed; +} md_state_t; + +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; + int line_count; + int scroll; + int y; + int h; + int line_h; + int in_code = 0; + int i; + + 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); + 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); + 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); + + 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); + if (scroll < 0) scroll = 0; + if (scroll > line_count) scroll = line_count; + + 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); + in_code = (packed & 0x10000) ? 1 : 0; + advance = packed & 0xffff; + if (advance <= 0) advance = line_h; + y += advance; + } + + return 0; +} + +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); +} + +static int md_view_buffer(ecex_t *ed, buffer_t *buffer) { + md_state_t *state; + 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)); + if (!state) return -1; + state->ed = ed; + + if (ecex_buffer_set_renderer(buffer, md_render, state, md_free_state, ECEX_RENDER_REPLACE_CONTENT) != 0) { + ecex_object_free(ed, state); + return -1; + } + ecex_buffer_set_major_mode_by_name(ed, buffer, "markdown-mode"); + return 0; +} + +static int md_file_handler(ecex_t *ed, buffer_t *buffer) { + if (!buffer) return -1; + if (ecex_buffer_has_renderer(buffer)) return 0; + return md_view_buffer(ed, buffer); +} + +static int cmd_markdown_view(ecex_t *ed) { + return md_view_buffer(ed, ecex_current_buffer(ed)); +} + +static int cmd_markdown_source(ecex_t *ed) { + buffer_t *buffer = ecex_current_buffer(ed); + if (!buffer) return -1; + if (ecex_buffer_has_renderer(buffer)) ecex_buffer_clear_renderer(buffer); + ecex_buffer_set_major_mode_by_name(ed, buffer, "markdown-mode"); + return 0; +} + +static int cmd_markdown_toggle(ecex_t *ed) { + buffer_t *buffer = ecex_current_buffer(ed); + if (!buffer) return -1; + if (ecex_buffer_has_renderer(buffer)) return cmd_markdown_source(ed); + return md_view_buffer(ed, buffer); +} + +int ecex_markdown_plugin(ecex_t *ed) { + 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); + return 0; +} + +#ifndef ECEX_NO_STANDALONE_CONFIG +ECEX_CONFIG_BEGIN + ECEX_CONFIG_INCLUDE(ecex_markdown_plugin); +ECEX_CONFIG_END +#endif -- cgit v1.2.3