degesch: add a prompt hook

This commit is contained in:
Přemysl Eric Janouch 2016-10-28 01:01:27 +02:00
parent 278e2b236b
commit b60bdf119a
Signed by: p
GPG Key ID: B715679E3A361BE6
1 changed files with 76 additions and 1 deletions

View File

@ -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 },