aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sam.c6
-rw-r--r--vis-cmds.c44
-rw-r--r--vis-core.h1
-rw-r--r--vis.c1
-rw-r--r--vis.h8
5 files changed, 59 insertions, 1 deletions
diff --git a/sam.c b/sam.c
index c52b2e1..7227438 100644
--- a/sam.c
+++ b/sam.c
@@ -109,6 +109,7 @@ static bool cmd_help(Vis*, Win*, Command*, const char *argv[], Cursor*, Filerang
static bool cmd_map(Vis*, Win*, Command*, const char *argv[], Cursor*, Filerange*);
static bool cmd_unmap(Vis*, Win*, Command*, const char *argv[], Cursor*, Filerange*);
static bool cmd_langmap(Vis*, Win*, Command*, const char *argv[], Cursor*, Filerange*);
+static bool cmd_user(Vis*, Win*, Command*, const char *argv[], Cursor*, Filerange*);
/* command recognized at the ':'-prompt. commands are found using a unique
* prefix match. that is if a command should be available under an abbreviation
@@ -161,7 +162,10 @@ static const CommandDef cmds[] = {
};
static const CommandDef cmddef_select =
- { { "s" }, 0, NULL, cmd_select };
+ { { NULL }, 0, NULL, cmd_select };
+
+static const CommandDef cmddef_user =
+ { { NULL }, CMD_ARGV|CMD_FORCE|CMD_ONCE, NULL, cmd_user };
bool sam_init(Vis *vis) {
if (!(vis->cmds = map_new()))
diff --git a/vis-cmds.c b/vis-cmds.c
index 7d3e0ab..63f91cb 100644
--- a/vis-cmds.c
+++ b/vis-cmds.c
@@ -4,6 +4,50 @@
#define VIS_OPEN "vis-open"
#endif
+typedef struct {
+ CmdFunc func;
+ void *data;
+} CmdUser;
+
+bool vis_cmd_register(Vis *vis, const char *name, void *data, CmdFunc func) {
+ if (!name)
+ return false;
+ if (!vis->usercmds && !(vis->usercmds = map_new()))
+ return false;
+ CmdUser *cmd = calloc(1, sizeof *cmd);
+ if (!cmd)
+ return false;
+ cmd->func = func;
+ cmd->data = data;
+ if (!map_put(vis->cmds, name, &cmddef_user))
+ goto err;
+ if (!map_put(vis->usercmds, name, cmd)) {
+ map_delete(vis->cmds, name);
+ goto err;
+ }
+ return true;
+err:
+ free(cmd);
+ return false;
+}
+
+bool vis_cmd_unregister(Vis *vis, const char *name) {
+ if (!name)
+ return true;
+ CmdUser *cmd = map_delete(vis->usercmds, name);
+ if (!cmd)
+ return false;
+ if (!map_delete(vis->cmds, name))
+ return false;
+ free(cmd);
+ return true;
+}
+
+static bool cmd_user(Vis *vis, Win *win, Command *cmd, const char *argv[], Cursor *cur, Filerange *range) {
+ CmdUser *user = map_get(vis->usercmds, argv[0]);
+ return user && user->func(vis, win, user->data, cmd->flags == '!', argv, cur, range);
+}
+
static void windows_arrange(Vis *vis, enum UiLayout layout) {
vis->ui->arrange(vis->ui, layout);
}
diff --git a/vis-core.h b/vis-core.h
index 5480589..606ff9b 100644
--- a/vis-core.h
+++ b/vis-core.h
@@ -153,6 +153,7 @@ struct Vis {
bool expandtab; /* whether typed tabs should be converted to spaces */
bool autoindent; /* whether indentation should be copied from previous line on newline */
Map *cmds; /* ":"-commands, used for unique prefix queries */
+ Map *usercmds; /* user registered ":"-commands */
Map *options; /* ":set"-options */
Map *keymap; /* key translation before any bindings are matched */
Buffer input_queue; /* holds pending input keys */
diff --git a/vis.c b/vis.c
index 388bc41..4abba5f 100644
--- a/vis.c
+++ b/vis.c
@@ -394,6 +394,7 @@ void vis_free(Vis *vis) {
register_release(&vis->registers[i]);
vis->ui->free(vis->ui);
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 6f60e6a..69b2586 100644
--- a/vis.h
+++ b/vis.h
@@ -396,6 +396,14 @@ void vis_cancel(Vis*);
/* execute a :-command (including an optinal range specifier) */
bool vis_cmd(Vis*, const char *cmd);
+
+/* type of user defined function which can be registered */
+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_unregister(Vis*, const char *name);
/* execute any kind (:,?,/) of prompt command */
bool vis_prompt_cmd(Vis*, const char *cmd);