From b60bdf119a15856567729b33f328f7c770e3c1ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Janouch?= Date: Fri, 28 Oct 2016 01:01:27 +0200 Subject: [PATCH] degesch: add a prompt hook --- degesch.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/degesch.c b/degesch.c index d407eb8..8b1ee4e 100644 --- a/degesch.c +++ b/degesch.c @@ -1984,6 +1984,20 @@ struct irc_hook_vtable // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +struct prompt_hook +{ + struct hook super; ///< Common hook fields + struct prompt_hook_vtable *vtable; ///< Methods +}; + +struct prompt_hook_vtable +{ + /// Returns what the prompt should look like right now based on other state + char *(*make) (struct prompt_hook *self); +}; + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + struct completion_word { size_t start; ///< Offset to start of word @@ -2086,6 +2100,7 @@ struct app_context struct plugin *plugins; ///< Loaded plugins struct hook *input_hooks; ///< Input hooks struct hook *irc_hooks; ///< IRC hooks + struct hook *prompt_hooks; ///< Prompt hooks struct hook *completion_hooks; ///< Autocomplete hooks } *g_ctx; @@ -5920,6 +5935,18 @@ make_server_postfix (struct buffer *buffer, struct str *output) static void make_prompt (struct app_context *ctx, struct str *output) { + LIST_FOR_EACH (struct hook, iter, ctx->prompt_hooks) + { + struct prompt_hook *hook = (struct prompt_hook *) iter; + char *made = hook->vtable->make (hook); + if (made) + { + str_append (output, made); + free (made); + return; + } + } + struct buffer *buffer = ctx->current_buffer; if (!buffer) return; @@ -5954,6 +5981,7 @@ make_prompt (struct app_context *ctx, struct str *output) make_server_postfix (buffer, output); str_append_c (output, ']'); + str_append_c (output, ' '); } static void @@ -5976,7 +6004,6 @@ on_refresh_prompt (struct app_context *ctx) struct str prompt; str_init (&prompt); make_prompt (ctx, &prompt); - str_append_c (&prompt, ' '); char *localized = iconv_xstrdup (ctx->term_from_utf8, prompt.str, -1, NULL); str_free (&prompt); @@ -8752,6 +8779,7 @@ enum lua_hook_type XLUA_HOOK_DEFUNCT, ///< No longer functional XLUA_HOOK_INPUT, ///< Input hook XLUA_HOOK_IRC, ///< IRC hook + XLUA_HOOK_PROMPT, ///< Prompt hook XLUA_HOOK_COMPLETION, ///< Autocomplete XLUA_HOOK_TIMER, ///< One-shot timer }; @@ -8766,6 +8794,7 @@ struct lua_hook struct hook hook; ///< Hook base structure struct input_hook input_hook; ///< Input hook struct irc_hook irc_hook; ///< IRC hook + struct prompt_hook prompt_hook; ///< IRC hook struct completion_hook c_hook; ///< Autocomplete hook struct poller_timer timer; ///< Timer @@ -8785,6 +8814,9 @@ lua_hook_unhook (lua_State *L) case XLUA_HOOK_IRC: LIST_UNLINK (hook->plugin->ctx->irc_hooks, &hook->data.hook); break; + case XLUA_HOOK_PROMPT: + LIST_UNLINK (hook->plugin->ctx->prompt_hooks, &hook->data.hook); + break; case XLUA_HOOK_COMPLETION: LIST_UNLINK (hook->plugin->ctx->completion_hooks, &hook->data.hook); break; @@ -8879,6 +8911,36 @@ struct irc_hook_vtable lua_irc_hook_vtable = // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +static char * +lua_prompt_hook_make (struct prompt_hook *self) +{ + struct lua_hook *hook = + CONTAINER_OF (self, struct lua_hook, data.prompt_hook); + struct lua_plugin *plugin = hook->plugin; + lua_State *L = plugin->L; + + lua_rawgeti (L, LUA_REGISTRYINDEX, hook->ref_callback); + lua_rawgetp (L, LUA_REGISTRYINDEX, hook); // 1: hook + + struct error *e = NULL; + char *prompt = xstrdup (""); + if (lua_plugin_call (plugin, 1, 1, &e)) + { + lua_plugin_handle_string_filter_result (plugin, &prompt, false, &e); + lua_pop (L, 1); + } + if (e) + lua_plugin_log_error (plugin, "Prompt hook", e); + return prompt; +} + +struct prompt_hook_vtable lua_prompt_hook_vtable = +{ + .make = lua_prompt_hook_make, +}; + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + static void lua_plugin_push_completion (lua_State *L, struct completion *data) { @@ -9037,6 +9099,18 @@ lua_plugin_hook_irc (lua_State *L) return 1; } +static int +lua_plugin_hook_prompt (lua_State *L) +{ + struct lua_plugin *plugin = lua_touserdata (L, lua_upvalueindex (1)); + struct lua_hook *hook = lua_plugin_push_hook + (plugin, 1, XLUA_HOOK_PROMPT, luaL_optinteger (L, 2, 0)); + hook->data.prompt_hook.vtable = &lua_prompt_hook_vtable; + plugin->ctx->prompt_hooks = + hook_insert (plugin->ctx->prompt_hooks, &hook->data.hook); + return 1; +} + static int lua_plugin_hook_completion (lua_State *L) { @@ -9745,6 +9819,7 @@ static luaL_Reg lua_plugin_library[] = { "parse", lua_plugin_parse }, { "hook_input", lua_plugin_hook_input }, { "hook_irc", lua_plugin_hook_irc }, + { "hook_prompt", lua_plugin_hook_prompt }, { "hook_completion", lua_plugin_hook_completion }, { "hook_timer", lua_plugin_hook_timer }, { "setup_config", lua_plugin_setup_config },