aboutsummaryrefslogtreecommitdiff
path: root/config/which_key_plugin.c
diff options
context:
space:
mode:
authorDavid Moc <personal@cdatgoose.org>2026-06-02 13:50:21 +0200
committerDavid Moc <personal@cdatgoose.org>2026-06-02 13:50:21 +0200
commita15cb041654ae307add0b998b526c87c3f42bf5f (patch)
tree225bb4b70e9fa05aa5f4d2722a1a9cf5fc6fca7f /config/which_key_plugin.c
parent6aeaa171dc1ca43392f53cbd02097f76e1b1c5a0 (diff)
Add plugin hooks and mode plugins
Diffstat (limited to 'config/which_key_plugin.c')
-rw-r--r--config/which_key_plugin.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/config/which_key_plugin.c b/config/which_key_plugin.c
new file mode 100644
index 0000000..8d4fb50
--- /dev/null
+++ b/config/which_key_plugin.c
@@ -0,0 +1,107 @@
+#include "ecex.h"
+
+#define WK_HOOK_NAME "which-key"
+#define WK_SLOT_ENABLED "enabled"
+
+typedef struct which_key_state {
+ ecex_plugin_t *plugin;
+ int showing;
+} which_key_state_t;
+
+static int which_key_enabled(ecex_plugin_t *plugin) {
+ return ecex_plugin_slot_i32_get_scalar(plugin, WK_SLOT_ENABLED, 1) != 0;
+}
+
+static int cmd_which_key_toggle(ecex_t *ed) {
+ ecex_plugin_t *plugin = ecex_plugin_find(ed, "which-key");
+ if (!plugin) return -1;
+
+ int enabled = !which_key_enabled(plugin);
+ ecex_plugin_slot_i32_set_scalar(plugin, WK_SLOT_ENABLED, enabled);
+ ecex_message(ed, enabled ? "which-key enabled" : "which-key disabled");
+ return 0;
+}
+
+static void which_key_prefix_hook(ecex_t *ed, const char *prefix, int event, void *userdata) {
+ which_key_state_t *state = (which_key_state_t *)userdata;
+ char line[1024];
+
+ if (!ed || !state || !state->plugin) return;
+ if (!which_key_enabled(state->plugin)) {
+ if (state->showing) ecex_message(ed, "");
+ state->showing = 0;
+ return;
+ }
+
+ if (event == ECEX_PREFIX_HOOK_CANCEL ||
+ event == ECEX_PREFIX_HOOK_FINISH ||
+ event == ECEX_PREFIX_HOOK_UNDEFINED) {
+ if (state->showing) ecex_message(ed, "");
+ state->showing = 0;
+ return;
+ }
+
+ if (event != ECEX_PREFIX_HOOK_BEGIN && event != ECEX_PREFIX_HOOK_UPDATE) {
+ return;
+ }
+
+ if (ecex_describe_key_prefix(ed, ecex_current_buffer(ed), prefix, line, sizeof(line), 24) >= 0) {
+ ecex_message(ed, line);
+ state->showing = 1;
+ }
+}
+
+static void which_key_command_hook(ecex_t *ed,
+ const char *command,
+ int event,
+ int result,
+ void *userdata) {
+ (void)command;
+ (void)result;
+
+ which_key_state_t *state = (which_key_state_t *)userdata;
+ if (event == ECEX_COMMAND_HOOK_AFTER && state && state->showing) {
+ ecex_plugin_t *plugin = state->plugin ? state->plugin : ecex_plugin_find(ed, "which-key");
+ if (plugin) {
+ ecex_message(ed, "");
+ state->showing = 0;
+ }
+ }
+}
+
+static void which_key_free(void *userdata) {
+ which_key_state_t *state = (which_key_state_t *)userdata;
+ if (!state) return;
+ ecex_plugin_object_free(state->plugin, state);
+}
+
+ECEX_PLUGIN_BEGIN(ecex_which_key_plugin, "which-key")
+ if (ecex_plugin_slot_i32_get_scalar(plugin, WK_SLOT_ENABLED, -1) < 0) {
+ ecex_plugin_slot_i32_set_scalar(plugin, WK_SLOT_ENABLED, 1);
+ }
+
+ ECEX_CONFIG_COMMAND("which-key-toggle", cmd_which_key_toggle);
+
+ which_key_state_t *state = ecex_plugin_object_calloc(plugin, "state", 1, sizeof(*state));
+ if (!state) return -1;
+ state->plugin = plugin;
+
+ if (ecex_add_command_hook(ed, WK_HOOK_NAME, which_key_command_hook, state, 0) != 0) {
+ ecex_plugin_object_free(plugin, state);
+ return -1;
+ }
+
+ if (ecex_add_prefix_hook(ed, WK_HOOK_NAME, which_key_prefix_hook, state, which_key_free) != 0) {
+ ecex_remove_command_hook(ed, WK_HOOK_NAME);
+ ecex_plugin_object_free(plugin, state);
+ return -1;
+ }
+
+ return 0;
+ECEX_PLUGIN_END
+
+#ifndef ECEX_NO_STANDALONE_CONFIG
+ECEX_CONFIG_BEGIN
+ ECEX_CONFIG_INCLUDE(ecex_which_key_plugin);
+ECEX_CONFIG_END
+#endif