From aff8ffe0646899d5bedf6a8d2d88fff257645c45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Sat, 31 Dec 2016 19:31:32 +0100 Subject: vis: allow user registered :-commands to specify a help text --- sam.c | 4 ---- vis-cmds.c | 20 +++++++++++++++++--- vis-lua.c | 4 +++- vis.c | 6 +++++- vis.h | 2 +- 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/sam.c b/sam.c index 6aedf70..287b645 100644 --- a/sam.c +++ b/sam.c @@ -258,10 +258,6 @@ static const CommandDef cmddef_select = { NULL, NULL, CMD_NONE, NULL, cmd_select }; -static const CommandDef cmddef_user = { - NULL, NULL, CMD_ARGV|CMD_FORCE|CMD_ONCE|CMD_ADDRESS_ALL, NULL, cmd_user -}; - /* :set command options */ typedef struct { const char *names[3]; /* name and optional alias */ diff --git a/vis-cmds.c b/vis-cmds.c index 6d836ce..a64e5f0 100644 --- a/vis-cmds.c +++ b/vis-cmds.c @@ -3,12 +3,14 @@ #include #include "vis-lua.h" +// FIXME: avoid this redirection? typedef struct { + CommandDef def; CmdFunc *func; void *data; } CmdUser; -bool vis_cmd_register(Vis *vis, const char *name, void *data, CmdFunc *func) { +bool vis_cmd_register(Vis *vis, const char *name, const char *help, void *data, CmdFunc *func) { if (!name) return false; if (!vis->usercmds && !(vis->usercmds = map_new())) @@ -16,9 +18,15 @@ bool vis_cmd_register(Vis *vis, const char *name, void *data, CmdFunc *func) { CmdUser *cmd = calloc(1, sizeof *cmd); if (!cmd) return false; + if (!(cmd->def.name = strdup(name))) + goto err; + if (help && !(cmd->def.help = strdup(help))) + goto err; + cmd->def.flags = CMD_ARGV|CMD_FORCE|CMD_ONCE|CMD_ADDRESS_ALL; + cmd->def.func = cmd_user; cmd->func = func; cmd->data = data; - if (!map_put(vis->cmds, name, &cmddef_user)) + if (!map_put(vis->cmds, name, &cmd->def)) goto err; if (!map_put(vis->usercmds, name, cmd)) { map_delete(vis->cmds, name); @@ -26,6 +34,8 @@ bool vis_cmd_register(Vis *vis, const char *name, void *data, CmdFunc *func) { } return true; err: + free((char*)cmd->def.name); + free((char*)cmd->def.help); free(cmd); return false; } @@ -33,11 +43,15 @@ err: bool vis_cmd_unregister(Vis *vis, const char *name) { if (!name) return true; - CmdUser *cmd = map_delete(vis->usercmds, name); + CmdUser *cmd = map_get(vis->usercmds, name); if (!cmd) return false; if (!map_delete(vis->cmds, name)) return false; + if (!map_delete(vis->usercmds, name)) + return false; + free((char*)cmd->def.name); + free((char*)cmd->def.help); free(cmd); return true; } diff --git a/vis-lua.c b/vis-lua.c index 5c8c46e..8925d24 100644 --- a/vis-lua.c +++ b/vis-lua.c @@ -903,6 +903,7 @@ static bool command_lua(Vis *vis, Win *win, void *data, bool force, const char * * @function command_register * @tparam string name the command name * @tparam function command the Lua function implementing the command + * @tparam[opt] string help the single line help text as displayed in `:help` * @treturn bool whether the command has been successfully registered * @usage * TODO @@ -911,7 +912,8 @@ static int command_register(lua_State *L) { Vis *vis = obj_ref_check(L, 1, "vis"); const char *name = luaL_checkstring(L, 2); const void *func = func_ref_new(L, 3); - bool ret = vis_cmd_register(vis, name, (void*)func, command_lua); + const char *help = luaL_optstring(L, 4, ""); + bool ret = vis_cmd_register(vis, name, help, (void*)func, command_lua); lua_pushboolean(L, ret); return 1; } diff --git a/vis.c b/vis.c index 444d56e..43534a2 100644 --- a/vis.c +++ b/vis.c @@ -562,8 +562,12 @@ void vis_free(Vis *vis) { for (int i = 0; i < LENGTH(vis->registers); i++) register_release(&vis->registers[i]); vis->ui->free(vis->ui); + if (vis->usercmds) { + const char *name; + while (map_first(vis->usercmds, &name) && vis_cmd_unregister(vis, name)); + } + map_free(vis->usercmds); map_free(vis->cmds); - map_free_full(vis->usercmds); map_free(vis->options); map_free(vis->actions); map_free(vis->keymap); diff --git a/vis.h b/vis.h index 192e5d2..8f76405 100644 --- a/vis.h +++ b/vis.h @@ -452,7 +452,7 @@ typedef bool (CmdFunc)(Vis*, Win*, void *data, bool force, const char *argv[], Cursor*, Filerange*); /* the function will be invoked whenever a command which matches a * unique prefix of the given name is executed */ -bool vis_cmd_register(Vis*, const char *name, void *data, CmdFunc*); +bool vis_cmd_register(Vis*, const char *name, const char *help, void *data, CmdFunc*); bool vis_cmd_unregister(Vis*, const char *name); /* execute any kind (:,?,/) of prompt command */ bool vis_prompt_cmd(Vis*, const char *cmd); -- cgit v1.2.3