Skip to content

Commit

Permalink
vis: add infrastructure to register custom :-commands
Browse files Browse the repository at this point in the history
  • Loading branch information
martanne committed Apr 21, 2016
1 parent 59b8834 commit 7b1f313
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 1 deletion.
6 changes: 5 additions & 1 deletion sam.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()))
Expand Down
44 changes: 44 additions & 0 deletions vis-cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
1 change: 1 addition & 0 deletions vis-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
1 change: 1 addition & 0 deletions vis.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
8 changes: 8 additions & 0 deletions vis.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit 7b1f313

Please sign in to comment.