#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